var Users = mongoose.model('user');
var fs = require("fs");
var async = require('async');
var path = require('path');
var Community = mongoose.model('community');
var userService = require('../services/userService');
/* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
var appService = require('../services/appService');
/* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   end */
var UserFollowups = mongoose.model('user_followups');
var toolUtil = require('../common/utils/toolUtil');
var mysqlUtil = require('../common/utils/mysqlUtil');
var messageUtil = require('../common/utils/messageUtil');
var Question = mongoose.model('question');
var cacheUtil = require('../common/utils/cacheUtil');
var SystemMessage = mongoose.model('system_messages');
var operateMessage = mongoose.model('system_operateMessages');
var Activity = mongoose.model('activity');
var Goods = mongoose.model('goods');
var moment = require('moment');
var SystemBanner = mongoose.model('system_BannerDefinitions');
var Bulletins = mongoose.model('community_bulletins');
var questionService = require('../services/questionService');
var Relation = mongoose.model('Relation_userAcitvity');
var QuestionReplyStatistics = mongoose.model('question_replystatistics');
var appHomeModules = mongoose.model('system_appHomeModules');
var userPortrait = mongoose.model('masterData_UserPortrait');
var adminUsers = mongoose.model('backoffice_adminusers');
var QuestionReplyPraise = mongoose.model('question_replypraises');
var userAuthentication = mongoose.model('user_authentications');
var md5 = require('MD5');
var specialTopics = mongoose.model('system_specialTopics');
var freshNews = mongoose.model('system_freshNews');
var roleAction = mongoose.model('masterData_roleActions');
var userCommunity = mongoose.model('user_community');
/*  宝宝树66小区二次改造    add  小区切换 luolh  20170803   start   */
var AmbassadorCommunity = mongoose.model('ambassador_community');
/*  宝宝树66小区二次改造    add  小区切换 luolh  20170803   end   */
var ugcIndex = mongoose.model('system_ugcIndex');
var neighbourActivity = mongoose.model('activity_neighbour');
var ugcReply = mongoose.model('system_ugcReply');
var promotionCode = mongoose.model('system_promotionCode');
var AdoptedCount = mongoose.model('question_adoptedcounts');
var pinyin = require("pinyin");
var inviteBind = mongoose.model('invite_wechat_bind');
var deviceCodeBind = mongoose.model('relation_deviceCodeBind');
var chatMessage = mongoose.model('system_chatMessages');
var recentContact = mongoose.model('user_recentContactPerson');
var replyAt = mongoose.model('question_replyAt');
var Banner = mongoose.model('community_banner');
var BannerBind = mongoose.model('community_banner_bind');
var questionPraise = mongoose.model('question_praise');
var userWant = mongoose.model('user_i_want');
var Dic = mongoose.model('masterData_Dictionaries');
var pushParamsMap = mongoose.model('system_pushParamsMap');
var userInvitation = mongoose.model('user_invitation');
var redisKey = require('../config/redisKey');
var communityApplication = mongoose.model('community_applications');
var UserTask = mongoose.model('user_task');
var Region = mongoose.model('masterData_Regions');
var RegionUser = mongoose.model('masterData_Regions_user');
// var Group = mongoose.model('group_family');
var Group = mongoose.model('group_family');
/*  宝宝树66小区二次改造    add   chenf  20170720   start   */
var taskService = require('./taskService');
var ambassadorCommunity = mongoose.model('ambassador_community');
var RoleApply = mongoose.model('user_role_apply');
/*  宝宝树66小区二次改造    add   chenf  20170720   end   */
var Geetest = require('gt3-sdk');

exports.registerService = function (userName, email, mobilePhone, userPassword, clientId, callback) {

    var args = {
        data: {
            username: mobilePhone,
            password: mobilePhone
        },
        headers: {"Content-Type": "application/json"}
    };
    restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
        if (response.statusCode = 200) {
            toolUtil.getInvitationCode(function (err, code) {
                var tempUser = new Users();
                tempUser.userName = userName;
                tempUser.email = email;
                tempUser.mobilePhone = mobilePhone;
                tempUser.userPassword = userPassword;
                tempUser.invitationCode = code;
                var img = {
                    "imageURL": defaultImage
                };
                tempUser.images.push(img);
                tempUser.clientId = clientId;
                if (userName) {
                    tempUser.huanxinUserName = userName;
                } else if (email) {
                    tempUser.huanxinUserName = email;
                } else {
                    tempUser.huanxinUserName = mobilePhone;
                }
                tempUser.save(callback);
            });
        } else {
            var msg = {
                "message": "用户名已存在"
            };
            callback(msg, null);
        }
    }).on('error', function (err) {
        logger.error(err);
        var msg = {
            "message": "用户名已存在"
        };
        callback(msg, null);
    });
};

exports.bindClientIdService = function (clientId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null);
        } else {
            async.series([
                function (callbackInner) {
                    Users.find({clientId: clientId}, '_id clientId', function (err, users) {
                        if (users != null && users.length > 0) {
                            async.each(users, function (user, callback1) {
                                user.clientId = undefined;
                                user.save(callback1);
                            }, function (err) {
                                callbackInner(err, null);
                            })
                        } else {
                            callbackInner(err, null);
                        }
                    })
                },
                function (callbackInner) {
                    Users.update({_id: user._id}, {clientId: clientId}, callbackInner);
                }
            ], callback);
        }
    });
};

exports.checkTokenService = function (token, vCode, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null)
        } else {
            async.series([
                function (callbackInner) {
                    if (user.roomUnit != null && user.roomUnit != '')
                        user.roomUnit = Number(vCode) >= 106000 && !isNaN(user.roomUnit) ? user.roomUnit + '单元' : user.roomUnit;

                    if (user.images.length == 1) {
                        user.images.push(user.images[0])
                    }

                    if (user.communityWay == null) {
                        user.communityWay = 1;
                    }

                    callbackInner(null, user);
                },
                function (callbackInner) {
                    var role;
                    if (user.authenticationStatus) {
                        role = 'vip'
                    } else {
                        role = 'vip'
                    }
                    var data = [];
                    roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                        if (results != null) {
                            results.forEach(function (temp) {
                                data.push(temp.action.tag);
                            })
                        }
                        callbackInner(err, data);
                    });
                },
                function (callbackInner) {
                    if (user.community) {
                        userAuthentication.findOne({
                            user: user._id,
                            isValid: true,
                            community: user.community._id
                        }, 'status', function (err, result) {
                            var data;
                            if (result == null) {
                                data = 0
                            } else {
                                if (result.status) {
                                    data = 1
                                } else {
                                    data = 2
                                }
                            }
                            callbackInner(err, data);
                        })
                    } else {
                        callbackInner(null, 0);
                    }
                },
                function (callbackInner) {
                    var key = 'app:signin:' + moment().format('YYYYMMDD');

                    redisClient.SISMEMBER(key, user._id, function (err, result) {
                        if (result == 1) {
                            callbackInner(null, true)
                        } else {
                            callbackInner(null, false)
                        }
                    });
                },
                function (callbackInner) {
                    communityApplication.findOne({
                        isValid: true,
                        user: user._id,
                        status: 0
                    }, 'communityName', function (err, result) {
                        callbackInner(err, (result && user.community == null) ? result.communityName : null);
                    })
                },
                function (callbackInner) {
                    UserTask.findOne({
                        user: user._id,
                        type: 'novice',
                        deadline: {$gt: new Date()},
                        'subTask.status': false
                    }, 'name subTask', function (err, task) {
                        callbackInner(null, task != null);
                    })
                }
            ], callback)
        }
    }, 'checkToken');
};

exports.checkTokenNewService = function (password, token, callback) {

};


// TODO: Translate
exports.sendWelcomeNewsService = function (mobilePhone, callback) {
    Users.findOne({'nickName': '小6客服'}, function (err, result) {
        userService.addToContactListService(result._id, '66CustomerService', mobilePhone, function (err) {
            if (err) {
                callback(err, null);
            } else {
                toolUtil.getAndCacheHuanXinToken(function (err, token) {
                    var args = {
                        data: {
                            "target_type": "users",
                            "target": [mobilePhone],
                            "msg": {
                                "type": "txt",
                                "msg": "欢迎加入宝宝树66小区，在这里，你可以跟邻居宝妈一起交流育儿经验、发现周围好玩、好吃、好逛的亲子活动信息、让闲置变废为宝……更多功能等你开启，快去逛溜吧！"
                            },
                            "from": result.huanxinUserName,
                            "ext": {           //扩展属性, 由app自己定义.可以没有这个字段，但是如果有，值不能是“ext:null“这种形式，否则出错
                                "nickName": "小6客服",
                                "avatar": result.images[0].imageURL,
                                "objId": result._id
                            }
                        },
                        headers: {
                            "Content-Type": "application/json",
                            "Authorization": "Bearer " + token
                        }
                    };

                    restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/messages", args, function (data, response) {
                        callback(null, null);
                    }).on('error', function (err) {
                        logger.error('sendWelcomeNewsService' + err.message);
                    });
                });
            }
        })
    });
};

/**
 * userService.js
 *删除用户
 * @param userName
 * @param email
 * @param mobilePhone
 * @param callback
 *author：chenjinzhuan
 * */
exports.deleteService = function (userName, email, mobilePhone, callback) {
    Users.findOneAndRemove({userName: userName, email: email, mobilePhone: mobilePhone}, callback);
};

/**
 * userService.js
 *获取环信app的token
 *author：chenjinzhuan
 * */
exports.getHuanxinTokenService = function (callback) {
    //环信获取token开始

    toolUtil.getAndCacheHuanXinToken(function (err, token) {
        callback(err, token)
    });

};

exports.findByIdService = function (id, vCode, callback) {
    /*  宝宝树66小区二次改造    add   luolh  20170720   start   */
    // Users.findById(id, 'userName email mobilePhone birthDate nickName nickUpCnt age gender maritalStatus hasChildren images apartmentDetail hobbies community communityWay homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy userRole children userRole dateCreated')
    // Users.findById(id, 'userName email mobilePhone birthDate nickName nickUpCnt age gender maritalStatus hasChildren images apartmentDetail hobbies community communityWay homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy userRole children userRole dateCreated')
    Users.findById(id, 'userName encUserId email mobilePhone birthDate nickName nickUpCnt age gender maritalStatus hasChildren images apartmentDetail hobbies community communityWay homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy userRole children userRole dateCreated')
    /*  宝宝树66小区二次改造    add   luolh  20170720   end   */
        .populate('userPortrait', 'portraitURL value')
        .populate('community', '_id communityName communityName_en_US pinyin communityType communityAddress unitSwitch communityLogo cityId  provinceId countyId location price dateBuild')
        .populate('homeTown.country', '_id name')
        .populate('homeTown.province', '_id name')
        .populate('homeTown.city', '_id name')
        .populate('homeTown.county', '_id name')
        .populate('hobbies', '_id value').exec(function (err, result) {
            if (result != null) {
                result.invitationCode = undefined;

                if (!result.authenticationStatus) {
                }
                if (result.roomUnit != null && result.roomUnit != '')
                    result._doc.roomUnit = Number(vCode) >= 106000 && !isNaN(result.roomUnit) ? result.roomUnit + '单元' : result.roomUnit;

                if (result.hobbies != null && result.hobbies.length > 4) {
                    result._doc.hobbies = result.hobbies.slice(0, 4);
                }

                if (result.images.length == 1) {
                    result.images.push(result.images[0])
                }

                if (result.communityWay == null) {
                    result._doc.communityWay = 1;
                }

                if (result.community != null) {
                    // var comm = result.community.toJSON();
                    //
                    // comm.communityName_en_US = (comm.pinyin) ?
                    //     comm.pinyin.toUpperCase() : pinyin(comm.communityName, {style: pinyin.STYLE_NORMAL}).join('').toUpperCase();
                    //
                    // result._doc.community = comm;

                    userAuthentication.findOne({
                        user: id,
                        isValid: true,
                        community: result.community._id
                    }, 'status', function (err, auth) {
                        if (auth == null) {
                            result._doc.vStatus = 0;
                        } else {
                            if (auth.status) {
                                result._doc.vStatus = 1;
                            } else {
                                result._doc.vStatus = 2;
                            }
                        }
                        callback(err, result);
                    })
                } else {
                    callback(err, result)
                }
            } else {
                callback({err: '', message: 'can not find user by id ' + id})
            }
        });
};

exports.findPushTokenService = function (userId, callback) {
    Users.findById(userId, 'baiduMessagePushingToken').exec(callback)
};

exports.logoutService = function (token, callback) {

    var userId = token;
    if (token.length > 24) {
        userId = toolUtil.getUserIdByToken(token)
    }

    async.series([

        function (callbackInner) {
            cacheUtil.cacheDelete(userId, callbackInner);
        },
        function (callbackInner) {
            Users.findOne({_id: userId}, '_id clientId huanxinUserName', function (err, user) {
                user.clientId = undefined;
                user.save(callbackInner);
            })
        }
    ], callback)
};

// 1120-commit-master
exports.loginService = function (loginId, password, clientId, clientIp, callback) { // 新
// exports.loginService = function (loginId, password, clientId, clientIp, callback) { // 旧
    async.series([
            function (callbackInner) {
                Users.findOne({
                    mobilePhone: loginId,
                    userPassword: password
                }, '_id userName frozenOrNot email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus')
                    .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName pinyin communityAddress').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value').exec(callbackInner);
            },
            function (callbackInner) {
                if (clientId != null) {
                    Users.update({
                        $or: [{mobilePhone: loginId, userPassword: password}, {
                            wechatId: loginId,
                            userPassword: password
                        }]
                    }, {clientId: clientId}, callbackInner)
                } else {
                    callbackInner(null, null);
                }

            }
        ],
        callback);
};

/* 宝宝树66小区三次改造 mod guo.xiaomin 20170928 start */
// 美囤第三方登陆
exports.appMtLoginService = function (loginStr, loginId, encUserId, type, deviceId, channelId, ipAddr, callback) {
    logger.info('userService.appMtLoginService start...');
    var user;
    async.series([
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 001 start...');
            var platform = "";
            if (type == "android") {
                platform = "9";
            } else {
                platform = "8";
            }
            var params = {
                loginstr : loginStr,
                platform : platform,
                timestamp : moment().format('YYYYMMDDHHmmss'),
                signature : "none"
            };
            logger.debug(params);
            appService.getMeitunTokenService(params, function(err, tokenResult) {
                logger.info('appService.getMeitunTokenService start...');
                if (err) {
                    logger.error(err);
                    callbackInner(err);
                } else {
                    logger.info('appService.getMeitunTokenService success...');
                    var loginTokenResult = {
                        loginStr : loginStr,
                        token : tokenResult
                    };
                    logger.debug(loginTokenResult);
                    // 如果有数据，查看本地是否注册，如果未注册，注册上宝宝树的数据
                    Users.findOne({encUserId: encUserId}, '_id userName encUserId mobilePhone  nickName')
                        .exec(function (err, userResult) {
                            if (err) {
                                callbackInner(err);
                            } else if (userResult == null) {
                                /*  宝宝树66小区 宝宝树自动登录优化 mod luolh  20171101   start   */
                                // 取得宝宝树用户数据
                                appService.getBabytreeUserInfoService(encUserId, function(err, babyUserRes){
                                    if (err) {
                                        logger.error(err);
                                        callbackInner(err);
                                    } else {
                                        // 用户在66未注册，注册信息
                                        var input = {};
                                        var babyUserPhone = babyUserRes.phone;
                                        if(babyUserPhone) {
                                            input.mobilePhone = babyUserPhone;
                                            var nickName = babyUserRes.nickname;
                                            appService.checkLocalNickNameCanUse(nickName, function(err, flag) {
                                                logger.debug("宝宝树用户检查昵称..." + loginId + ',' + nickName + ',' + flag);
                                                if (!flag) {
                                                    nickName = nickName + toolUtil.getRandomNumberByNum(6);
                                                }
                                                input.nickName = nickName;
                                                input.channelId = channelId;
                                                input.deviceId = deviceId;
                                                input.encUserId = encUserId;
                                                logger.debug(input);
                                                appService.registerLocal(input, function(err, result){
                                                    if (err) {
                                                        logger.error(err);
                                                        callbackInner(err);
                                                    } else {
                                                        logger.debug("宝宝树用户隐形注册到66成功..." + loginId);
                                                        callbackInner(null, loginTokenResult);
                                                    }
                                                });
                                            });
                                        } else {
                                            var errorMessage = "当前宝宝树账号无法登陆，请在宝宝树绑定手机号。";
                                            logger.debug("当前宝宝树账号无法登陆，请在宝宝树绑定手机号。" + loginStr);
                                            callbackInner({"message": errorMessage});
                                        }
                                    }
                                });
                                /*  宝宝树66小区 宝宝树自动登录优化 mod luolh  20171101   end   */
                            } else {
                                // 已注册,修改掉enc_user_id, 把密码置空
                                Users.update({_id: userResult._id}, {encUserId:encUserId, userPassword : ''}, function(err, updateResult) {
                                    if (err) {
                                        logger.error("同步密码操作出错");
                                        callbackInner(err);
                                    } else {
                                        callbackInner(null, loginTokenResult);
                                    }
                                });
                            }
                        });
                }
            });
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 002 start...');
            var opt = {'encUserId': encUserId};
            Users.findOne(opt, '_id userName frozenOrNot encUserId email mobilePhone birthDate userRole nickName communityWay age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy children dateCreated')
                .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityName_en_US pinyin communityAddress communityLogo unitSwitch').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value')
                .exec(function (err, result) {
                    if (result != null && !result.authenticationStatus) {
                        result.invitationCode = undefined;
                    }

                    if (result != null && result.roomUnit != null && result.roomUnit != '')
                        result._doc.roomUnit = Number(vCode) >= 106000 && !isNaN(result.roomUnit) ? result.roomUnit + '单元' : result.roomUnit;

                    if (result != null && result.images.length == 1) {
                        result.images.push(result.images[0])
                    }

                    if (result != null && result.communityWay == null) {
                        result._doc.communityWay = 1;
                    }

                    user = result;
                    callbackInner(err, user);
                });
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 003 start...');
            if (user != null) {
                var role;
                if (user.authenticationStatus) {
                    role = 'vip'
                } else {
                    role = 'vip'
                }
                var data = [];
                roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                    if (results != null) {
                        results.forEach(function (temp) {
                            data.push(temp.action.tag);
                        })
                    }
                    callbackInner(err, data);
                });
            } else {
                callbackInner(null, null);
            }
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 004 start...');
            if (user && user.community) {
                userAuthentication.findOne({
                    user: user._id,
                    isValid: true,
                    community: user.community._id
                }, 'status', function (err, result) {
                    var data;
                    if (result == null) {
                        data = 0
                    } else {
                        if (result.status) {
                            data = 1
                        } else {
                            data = 2
                        }
                    }
                    callbackInner(err, data);
                })
            } else {
                callbackInner(null, 0);
            }
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 005 start...');
            var key = 'app:signin:' + moment().format('YYYYMMDD');

            if (user != null) {
                redisClient.SISMEMBER(key, user._id + '', function (err, result) {
                    if (result == 1) {
                        callbackInner(null, true)
                    } else {
                        callbackInner(null, false)
                    }
                });
            } else {
                callbackInner()
            }
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 006 start...');
            if (user != null) {
                communityApplication.findOne({
                    isValid: true,
                    user: user._id,
                    status: 0
                }, 'communityName', function (err, result) {
                    callbackInner(err, (result && user.community == null) ? result.communityName : null);
                })
            } else {
                callbackInner()
            }
        },
        function (callbackInner) {
            logger.debug('userService.appMtLoginService 007 start...');
            if (user != null) {
                UserTask.findOne({
                    user: user._id,
                    type: 'novice',
                    deadline: {$gt: new Date()},
                    'subTask.status': false
                }, 'name subTask', function (err, task) {
                    callbackInner(null, task != null);
                })
            } else {
                callbackInner();
            }
        }
    ], callback);

};
/* 宝宝树66小区三次改造 mod guo.xiaomin 20170928 end */

//新登录
/*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   start   */
//exports.appLoginService = function (loginId, password, thirdId, vCode, callback) {
exports.appLoginService = function (type, deviceId, channelId, loginId, password, thirdId, vCode, vName, clientIp, callback) { // 新
// exports.appLoginService = function (type, deviceId, channelId, loginId, password, thirdId, vCode, vName, callback) { // 旧
    /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   start   */
    var user;
    // var opt = {};
    // if (loginId != null) {
    //     opt = {
    //         mobilePhone: loginId,
    //         userPassword: md5(password)
    //     }
    // } else if (thirdId != null) {
    //     opt = {
    //         wechatId: thirdId
    //     }
    // }
    /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
    // 极验证SSO信息
    // var ssoInfoNoDataFlg = false;
    var ssoPwdErrorFlg = false;
    /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   end */
    async.series([
        /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
        function (callbackInner) {
            // 登录极验证,返回loginStr
            var params = [
                {name:'action', value:'mobile_login'},
                {name:'phone_number', value:loginId},
                {name:'password', value:password},
                {name:'client_ip', value: clientIp}
            ];
            // var url = "http://"+ssoUrl;
            var url = "http://" + ssoUrl + "/sso/meitun.sso.php";
            appService.getSsoTokenTailService(params, function(urlTail) {
                if (params.length > 0) {
                    url += "?" + urlTail;
                }
                logger.debug(url);
                restClient.get(url, function (data, response) {
                    logger.debug('restClient.get success...');
                    logger.debug('response.statusCode...' + response.statusCode);
                    if (response.statusCode == 200) {
                        var objData = JSON.parse(data);
                        if (1 == objData.status) {
                            // 返回数据正常
                            // input.encUserId = objData.data.enc_user_id;
                            var loginStr =  objData.data.login_string;
                            if (!loginStr) {
                                logger.error("loginStr为空:"+data);
                                callbackInner({status:0,message:"网络异常"});
                            } else {
                                // 根据loginStr取得token
                                var platform = "";
                                if (type == "android") {
                                    platform = "9";
                                } else {
                                    platform = "8";
                                }
                                var params = {
                                    loginstr : loginStr,
                                    platform : platform,
                                    timestamp : moment().format('YYYYMMDDHHmmss'),
                                    signature : "none"
                                };
                                logger.debug(params);
                                appService.getMeitunTokenService(params, function(err, tokenResult) {
                                    if (err) {
                                        logger.debug("exports.appLoginService appService.getMeitunTokenService error...");
                                        logger.error(err);
                                        callbackInner(err);
                                    } else {
                                        logger.debug("exports.appLoginService appService.getMeitunTokenService success...");
                                        var loginTokenResult = {
                                            loginStr : loginStr,
                                            token : tokenResult
                                        };
                                        logger.debug(loginTokenResult);
                                        // 如果有数据，查看本地是否注册，如果未注册，注册上宝宝树的数据
                                        /*  宝宝树66小区三次改造    mod   guo.xiaomin  20171017   start   */
                                        Users.findOne({mobilePhone: loginId}, '_id userName encUserId mobilePhone  nickName')
                                            .exec(function (err, userResult) {
                                                if (err) {
                                                    callbackInner(err);
                                                } else if (userResult == null) {
                                                    // 用户在66未注册，注册信息
                                                    var input = {};
                                                    input.mobilePhone = loginId;
                                                    // input.userPassword = password;
                                                    /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170904   start   */
                                                    // input.nickName = objData.data.nickname; // 旧
                                                    var nickName = objData.data.nickname;
                                                    appService.checkLocalNickNameCanUse(nickName, function(err, flag) {
                                                        logger.debug("宝宝树用户检查昵称..." + loginId + ',' + nickName + ',' + flag);
                                                        if (!flag) {
                                                            nickName = nickName + toolUtil.getRandomNumberByNum(6);
                                                        }
                                                        input.nickName = nickName;
                                                        /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170904   end   */
                                                        input.channelId = channelId;
                                                        input.deviceId = deviceId;
                                                        input.encUserId = objData.data.enc_user_id;
                                                        logger.debug(input);
                                                        appService.registerLocal(input, function(err, result){
                                                            if (err) {
                                                                logger.error(err);
                                                                callbackInner(err);
                                                            } else {
                                                                logger.debug("宝宝树用户隐形注册到66成功..." + loginId);
                                                                callbackInner(null, loginTokenResult);
                                                            }
                                                        });
                                                    });
                                                } else {
                                                    // 已注册,修改掉enc_user_id, 把密码置空
                                                    Users.update({_id: userResult._id}, {encUserId:objData.data.enc_user_id,userPassword : ''}, function(err, updateResult) {
                                                        if (err) {
                                                            logger.error("同步密码操作出错");
                                                            callbackInner(err);
                                                        } else {
                                                            callbackInner(null, loginTokenResult);
                                                        }
                                                    });
                                                }
                                            });
                                        /*  宝宝树66小区三次改造    mod   guo.xiaomin  20171017   end   */
                                    }
                                });
                            }
                        }
                        else {
                            // 宝宝树已经注册了，数据异常
                            // if (objData.error == 2) {
                            //     // 如果是没有数据, 需要验证本地是否注册，已注册是老用户，注册到babytree,没注册，无法登录
                            //     ssoInfoNoDataFlg = true;
                            //     callbackInner();
                            // } else {
                                if (objData.error == 41) {
                                    // 密码不匹配
                                    logger.debug("login->密码不匹配");
                                    ssoPwdErrorFlg = true;
                                    callbackInner();
                                } else {
                                    appService.getErrorMsg(objData.error, function(msg){
                                        logger.error(data+"," + msg);
                                        callbackInner({status: 0, message: msg});
                                    });
                                }
                            // }
                        }
                    } else {
                        logger.error(data);
                        callbackInner({status:0,message:"网络异常"});
                    }
                }).on('error', function (err) {
                    logger.error('restClient.get error...');
                    logger.error(err);
                    callbackInner(err);
                });
            });

        },
        /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   end */
        function (callbackInner) {
            var opt = {};
            /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
            if (ssoPwdErrorFlg == true) {
                // 如果宝宝树登录不成功(没有此用户，或者用户密码为空)，登录66小区
                if (loginId != null) {
                    opt = {
                        mobilePhone: loginId,
                        userPassword: md5(password)
                    }
                } else if (thirdId != null) {
                    opt = {
                        wechatId: thirdId
                    }
                }
            } else {
                // 如果登录宝宝树成功，取得宝宝树数据
                if (loginId != null) {
                    opt = {
                        mobilePhone: loginId,
                    }
                } else if (thirdId != null) {
                    opt = {
                        wechatId: thirdId
                    }
                }
            }
            // Users.findOne(opt, '_id userName frozenOrNot email mobilePhone birthDate userRole nickName communityWay age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy children dateCreated')
            Users.findOne(opt, '_id userName frozenOrNot encUserId email mobilePhone birthDate userRole nickName communityWay age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy children dateCreated')
                .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityName_en_US pinyin communityAddress communityLogo unitSwitch').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value')
                .exec(function (err, result) {
                    if (result != null && !result.authenticationStatus) {
                        result.invitationCode = undefined;
                    }

                    if (result != null && result.roomUnit != null && result.roomUnit != '')
                        result._doc.roomUnit = Number(vCode) >= 106000 && !isNaN(result.roomUnit) ? result.roomUnit + '单元' : result.roomUnit;

                    if (result != null && result.images.length == 1) {
                        result.images.push(result.images[0])
                    }

                    if (result != null && result.communityWay == null) {
                        result._doc.communityWay = 1;
                    }

                    // if (result && result.community) {
                    //     var comm = result.community.toJSON();
                    //
                    //     comm.communityName_en_US = (comm.pinyin) ?
                    //         comm.pinyin.toUpperCase() : pinyin(comm.communityName, {style: pinyin.STYLE_NORMAL}).join('').toUpperCase();
                    //
                    //     result._doc.community = comm;
                    //
                    // }

                    user = result;
                    callbackInner(err, user);
                });
            /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
        },
        /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   start */
        function(callbackInner){
            /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170901   start */
            // 注册老用户,登录新用户
            if(user != null && ssoPwdErrorFlg == true && user.encUserId != null && user.encUserId != "") {
                /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   start */
                logger.info("宝宝树用户存在,宝宝树登陆失败,66登陆成功!客户端版本号,vName:::" + vName);
                // 旧版本，登陆成功(当前版:4.4.0)
                if(vName != null && newAppVersion.indexOf(vName) == -1) {
                    logger.info("旧版(不等于v4.4.0且不等于4.4.1)正常登陆");
                    callbackInner(null, user);
                } else {
                    callbackInner({status:0,message:"您的账号存在安全隐患，请重新设置密码"});
                }
                /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   end */

            } else if (user != null && ssoPwdErrorFlg == true && (user.encUserId == null || user.encUserId == "")){
            /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170901   end */
                // 66小区注册了，宝宝树根据密码登录不可（未注册或注册密码不一致），注册olduser = 1(无check注册密码)

                // 没有注册宝宝树的情况下,注册到宝宝树,或者修改宝宝树

                /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   start */
                var nickName = user.nickName;

                appService.checkNickNameCanUse(nickName, function(err, flag) {
                    if(!flag) {
                        nickName = nickName + toolUtil.getRandomNumberByNum(6);
                    }

                    var input = {
                        nickName : nickName,
                        mobilePhone : loginId,
                        userPassword : password,
                        olduser : 1
                    };

                    appService.registerSsoService(input, function(err, clientIp, registerResult){ // 新
                    // appService.registerSsoService(input, function(err, registerResult){ // 旧
                        if (err) {
                            // 注册失败
                            logger.error(err);
                            callbackInner(err);
                        } else {
                            // 修正enc_user_id
                            logger.debug(registerResult.enc_user_id + ">注册后返回的数据>" + registerResult);
                            Users.update({_id: user._id}, {encUserId:registerResult.enc_user_id, userPassword:''}, function(err, result) {
                                logger.debug(result);
                                if (err) {
                                    // 修正本地失败
                                    logger.error("修改本地密码失败" + err);
                                    callbackInner(err);
                                } else {
                                    // 修正成功
                                    // 注册成功, 登录取得loginStr
                                    // 登录极验证,返回loginStr
                                    var params = [
                                        {name:'action', value:'mobile_login'},
                                        {name:'phone_number', value:loginId},
                                        {name:'password', value:password},
                                        {name:'client_ip', value: clientIp}
                                    ];
                                    var url = "http://"+ssoUrl;
                                    var url = "http://" + ssoUrl + "/sso/meitun.sso.php";
                                    appService.getSsoTokenTailService(params, function(urlTail) {
                                        if (params.length > 0) {
                                            url += "?" + urlTail;
                                        }
                                        // logger.debug(url);
                                        restClient.get(url, function (data, response) {
                                            if (response.statusCode == 200) {
                                                logger.debug("loginStr:"+data);
                                                var objData = JSON.parse(data);
                                                if (1 == objData.status) {
                                                    // 返回数据正常
                                                    // input.encUserId = objData.data.enc_user_id;
                                                    logger.debug(objData);
                                                    callbackInner(null, objData.data);
                                                }
                                                else {
                                                    // 宝宝树已经注册了，数据异常
                                                    if (objData.error == 2) {
                                                        // 如果是没有数据, 需要验证本地是否注册，已注册是老用户，注册到babytree,没注册，无法登录
                                                        logger.error("重新注册后宝宝树登录无数据：" + objData);
                                                        callbackInner({status:0, message : "网络异常"});
                                                    } else {
                                                        exports.getErrorMsg(objData.error, function(msg){
                                                            logger.error(objData+"," + msg);
                                                            callbackInner({status: 0, message: msg});
                                                        });
                                                    }
                                                }
                                            } else {
                                                logger.error(data);
                                                callbackInner({status:0,message:"登录极验证失败"});
                                            }
                                        }).on('error', function (err) {
                                            logger.error(err);
                                            callbackInner(err);
                                        });
                                    });
                                }
                            });
                        }
                    });
                });
                /* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   end */
            } else if (user != null && ssoPwdErrorFlg == false) {
                // 正常
                callbackInner();
            }
            else {
                if (user != null && ssoPwdErrorFlg == true) {
                    // 如果是邮件密码不匹配
                    logger.debug(loginId + "》宝宝树登录密码错误》"+password);
                    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170902   start   */
                    // callbackInner({status : 0 , message : "用户名或密码错误" }); // 旧
                    callbackInner({status : 0 , message : "请用正确的手机号和宝宝树密码登录" }); // 新
                    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170902   end   */
                } else {
                    logger.debug(loginId + "》66小区登录密码错误》"+password);
                    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170902   start   */
                    // callbackInner({status : 0 , message : "用户名或密码错误" }); // 旧
                    callbackInner({status : 0 , message : "请用正确的手机号和宝宝树密码登录" }); // 新
                    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170902   end   */
                }
            }
        },
        /* 宝宝树66小区二期拼团    add 登录注册接口变更  llh  20170822   end */
        function (callbackInner) {
            if (user != null) {
                var role;
                if (user.authenticationStatus) {
                    role = 'vip'
                } else {
                    role = 'vip'
                }
                var data = [];
                roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                    if (results != null) {
                        results.forEach(function (temp) {
                            data.push(temp.action.tag);
                        })
                    }
                    callbackInner(err, data);
                });
            } else {
                callbackInner(null, null);
            }
        },
        function (callbackInner) {
            if (user && user.community) {
                userAuthentication.findOne({
                    user: user._id,
                    isValid: true,
                    community: user.community._id
                }, 'status', function (err, result) {
                    var data;
                    if (result == null) {
                        data = 0
                    } else {
                        if (result.status) {
                            data = 1
                        } else {
                            data = 2
                        }
                    }
                    callbackInner(err, data);
                })
            } else {
                callbackInner(null, 0);
            }
        },
        function (callbackInner) {
            var key = 'app:signin:' + moment().format('YYYYMMDD');

            if (user != null) {
                redisClient.SISMEMBER(key, user._id + '', function (err, result) {
                    if (result == 1) {
                        callbackInner(null, true)
                    } else {
                        callbackInner(null, false)
                    }
                });
            } else {
                callbackInner()
            }
        },
        function (callbackInner) {
            if (user != null) {
                communityApplication.findOne({
                    isValid: true,
                    user: user._id,
                    status: 0
                }, 'communityName', function (err, result) {
                    callbackInner(err, (result && user.community == null) ? result.communityName : null);
                })
            } else {
                callbackInner()
            }
        },
        function (callbackInner) {
            if (user != null) {
                UserTask.findOne({
                    user: user._id,
                    type: 'novice',
                    deadline: {$gt: new Date()},
                    'subTask.status': false
                }, 'name subTask', function (err, task) {
                    callbackInner(null, task != null);
                })
            } else {
                callbackInner();
            }
        }
    ], callback);
};

/*  宝宝树66小区二次改造    add   guo.xiaomin  20170802   start   */
exports.getUserGagOrNotService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            Users.findOne({_id: user._id}, 'gagOrNot', function (err, result) {
                callback(err, result);
            });
        }
    })
};
/*  宝宝树66小区二次改造    add   guo.xiaomin  20170802   end   */

/**
 * 获取用户权限列表
 * @param token
 * @param callback
 */
exports.getUserAuthListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            Users.findOne({_id: user._id}, function (err, result) {
                var role;
                if (result.authenticationStatus) {
                    role = 'vip'
                } else {
                    role = 'vip'
                }
                var data = [];
                roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                    if (results != null) {
                        results.forEach(function (temp) {
                            data.push(temp.action.tag);
                        })
                    }
                    callback(err, data);
                });
            });
        }
    })
};

/**
 * 第三方登录接口 1.1.2开始
 */
exports.appThirdPartyLoginService = function (thirdId, input, deviceId, vCode, type, clientIp, callback) { // 新
// exports.appThirdPartyLoginService = function (thirdId, input, deviceId, vCode, type, callback) { // 旧
    var isRegister;
    async.series([
        function (callbackInner) {
            Users.findOne({wechatId: thirdId}, function (err, result) {
                isRegister = result ? false : true;
                callbackInner(null, null);
            });
        },
        function (callbackInner) {
            if (isRegister) {
                var key = 'app:user:device:register';

                redisClient.HGET(key, deviceId, function (err, value) {
                    if (value == null || (type == 'android' && Number(vCode) < 107000) || (value != null && value.split(',').length < REGISTER_LIMIT)) {
                        var args = {
                            data: {
                                username: thirdId,
                                password: thirdId
                            },
                            headers: {"Content-Type": "application/json"}
                        };
                        restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
                            if (response.statusCode == 200) {
                                toolUtil.getInvitationCode(function (err, code) {

                                    var regStr = '^' + thirdId + '$';
                                    inviteBind.findOne({
                                        unionId: {
                                            $regex: regStr,
                                            $options: "$i"
                                        }
                                    }, function (err, bind) {

                                        var tempUser = new Users();
                                        tempUser.huanxinUserName = thirdId;
                                        tempUser.huanxinPassword = thirdId;
                                        tempUser.wechatId = thirdId;
                                        tempUser.userPassword = md5(thirdId);
                                        tempUser.nickName = input.nickName;

                                        tempUser.pinyin = pinyin(input.nickName, {style: pinyin.STYLE_NORMAL}).join('').toLowerCase();
                                        tempUser.pinyinShort = pinyin(input.nickName, {style: pinyin.STYLE_FIRST_LETTER}).join('');
                                        tempUser.pinyinSort = tempUser.pinyin + '_' + (new Date()).getTime();

                                        tempUser.openId = input.openId;
                                        tempUser.loginWay = input.loginWay;
                                        tempUser.invitationCode = code;
                                        if (input.image == null || input.image == '') {
                                            input.image = defaultImage;
                                        }
                                        var img = {
                                            "imageURL": input.image
                                        };
                                        tempUser.images.push(img);

                                        if (bind && bind.fromUserId) {
                                            tempUser.invitedBy = bind.fromUserId;
                                        }

                                        tempUser.save(function (err, result) {
                                            redisClient.sadd('u:all', result._id);
                                            callbackInner(null, isRegister);

                                            //储存设置注册信息
                                            redisClient.HSET(key, deviceId, value == null ? result._id + '' : value + ',' + result._id);

                                            if (bind && bind.inviteCode) {
                                                var temp = new deviceCodeBind();
                                                temp.invitationCode = bind.inviteCode;
                                                temp.deviceId = deviceId;
                                                temp.user = result._id;
                                                temp.save();

                                                var inv = new userInvitation();
                                                inv.invitee = result._id;
                                                inv.inviter = bind.fromUserId;
                                                inv.save();
                                            }

                                        });
                                    });
                                })
                            } else {
                                var msg = {
                                    "message": "登录失败"
                                };
                                callbackInner(msg, null);
                            }
                        }).on('error', function (err) {
                            logger.error('init community around went wrong on the request' + err.message);
                            var msg = {
                                "message": "登录失败"
                            };
                            callbackInner(msg, null);
                        });
                    } else {
                        callbackInner({message: '手机注册达到上限'})
                    }
                });
            } else {
                callbackInner(null, isRegister);
            }
        },
        function (callbackInner) {
            /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   start   */
            // userService.appLoginService(null, null, thirdId, vCode, function (err, results) {
            userService.appLoginService(null, null, null, null, null, thirdId, vCode, null, clientIp, function (err, results) { // 新
            // userService.appLoginService(null, null, null, null, null, thirdId, vCode, null, function (err, results) { // 旧
                /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   end   */
                var user = results[0];
                if (user.frozenOrNot) {
                    var msg = {
                        message: '帐号被冻结'
                    };
                    callbackInner(msg, null);
                } else {
                    var token = results[0]._id;
                    //获取token并缓冲
                    user.frozenOrNot = undefined;
                    user._doc['token'] = token;
                    user._doc['auth'] = results[1];
                    user._doc['vStatus'] = results[2];
                    user._doc['isSignIn'] = results[3];

                    toolUtil.setUserByToken(token);

                    callbackInner(err, user);
                }
            });
        }
    ], callback)
};

/**
 * userService.js
 *微信登录
 *author：chenjinzhuan
 * */
exports.loginViaWeChatService = function (wechatId, nickName, image, clientId, callback) {

    wechatId = wechatId.toLowerCase();

    if (nickName == null) {
        var msg = {
            "message": "没有昵称"
        };
        callback(msg, null);
    } else {
        //根据微信统一id查找用户

        Users.findOne({wechatId: wechatId}, '_id userName frozenOrNot email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus')
            .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityAddress').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value')
            .exec(function (err, user) {
                if (err) {//查找出错的情况
                    logger.error('Exception happened in getContactListService...!');
                    return callback(err, null);
                } else if (user == null) {//用户不存在，则建立新用户
                    logger.debug('create a new wechat account...!');
                    var args = {
                        data: {
                            username: wechatId,
                            password: wechatId
                        },
                        headers: {"Content-Type": "application/json"}
                    };
                    restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
                        if (response.statusCode == 200) {
                            var tempUser = new Users();
                            tempUser.huanxinUserName = wechatId;
                            tempUser.huanxinPassword = wechatId;
                            tempUser.wechatId = wechatId;
                            tempUser.userPassword = md5(wechatId);
                            tempUser.nickName = nickName;
                            tempUser.clientId = clientId;
                            var images = [];
                            var img = {
                                "imageURL": image
                            };
                            tempUser.images.push(img);
                            tempUser.save(function (err, result) {
                                tempUser._doc['_id'] = result._id;
                                tempUser._doc['firstLogin'] = true;
                                callback(null, tempUser);
                            });

                        } else {
                            var msg = {
                                "message": "登录失败"
                            };
                            callback(msg, null);
                        }
                    }).on('error', function (err) {
                        logger.error('init community around went wrong on the request' + err.message);
                        var msg = {
                            "message": "登录失败"
                        };
                        callback(msg, null);
                    });

                } else {//用户存在，则返回用户的所有数据
                    //如果用户被冻结，则返回错误
                    if (user._doc.frozenOrNot == true) {
                        var msg = {
                            "message": "帐号被冻结"
                        };
                        callback(msg, null);
                    } else {
                        if (user._doc.nickName == null && nickName != null) {//如果昵称不存在，就添加昵称
                            Users.update({_id: user._id}, {'nickName': nickName}, function (err) {
                                if (err) {
                                    logger.debug("login by wechat wrong" + err);
                                }
                            });
                            user._doc["nickName"] = nickName;
                        }
                        if (user.images.length == 0 && image != null) {//如果头像不存在，就添加头像
                            var images = [];
                            var img = {
                                "imageURL": image
                            };
                            images.push(img);
                            Users.update({_id: user._id}, {$set: {'images': images}}, function (err) {
                                if (err) {
                                    logger.debug("login by wechat wrong" + err);
                                }
                            });
                            user._doc["images"] = images;
                        }
                        user._doc["firstLogin"] = false;
                        callback(null, user);
                    }
                }
            });
    }
};

exports.getUserAuthService = function (status, callback) {
    var role;
    if (status) {
        role = 'vip'
    } else {
        role = 'vip'
    }

    var data = [];
    roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
        if (results != null) {
            results.forEach(function (temp) {
                data.push(temp.action.tag);
            })
        }
        callback(err, data);
    });
};

/**
 * userService.js
 *重置密码
 *author：chenjinzhuan
 * */
exports.resetPasswordService = function (mobilePhone, newPassword, clientIp, callback) { // 新
// exports.resetPasswordService = function (mobilePhone, newPassword, callback) { // 旧
    async.waterfall([
        //更新数据库密码
        function (callbackInner) {
            Users.update({mobilePhone: mobilePhone}, {userPassword: md5(newPassword)}, function (err) {
                if (err) {
                    logger.debug('Exception happened in resetPasswordService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to reset the password in database ...');
                    callbackInner(null);
                }
            });
        },
        //更新最后修改日期
        function (callbackInner) {
            Users.update({mobilePhone: mobilePhone}, {dateLastModified: new Date()}, function (err) {
                if (err) {
                    logger.debug('Exception happened in resetPasswordService 2....');
                    return callback(err);
                } else {
                    logger.debug('succeed to change the dateLastModified ...');
                    callbackInner(null);
                }
            });
        }
    ], callback);
};


/**
 * userService.js
 *修改密码
 *author：chenjinzhuan
 * */
exports.changePaswordService = function (id, userName, input, clientIp, callback) { // 新
// exports.changePaswordService = function (id, userName, input, callback) { // 旧
    //所有的回调函数都应该有单独的函数实现，例如：function(err,user){}
    //回调函数如果加return，则会返回到对应的函数，如果不加return，则会继续执行
    async.waterfall([
        // 查询旧密码
        function (callbackInner) {
            Users.findOne({_id: id}, 'encUserId userPassword mobilePhone', function (err, result) {
                callbackInner(null, result);
            })
        },
        //判断旧密码是否正确
        function (user, callbackInner) {
            /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   start   */
            // 去掉userPassword的判断
            if (user.encUserId != null && user.encUserId != "") {
                // 联通数据，登录接口测试
                // 登录极验证
                var params = [
                    {name:'action', value:'mobile_login'},
                    {name:'phone_number', value:user.mobilePhone},
                    {name:'password', value:input.oldPassword},
                    {name:'client_ip', value: clientIp}
                ];
                // var url = "http://"+ssoUrl;
                var url = "http://" + ssoUrl + "/sso/meitun.sso.php";
                appService.getSsoTokenTailService(params, function(urlTail) {
                    if (params.length > 0) {
                        url += "?" + urlTail;
                    }
                    logger.debug(url);
                    restClient.get(url, function (data, response) {
                        if (response.statusCode == 200) {
                            var objData = JSON.parse(data);
                            if (1 == objData.status) {
                                 // 如果有数据，查看本地是否注册，如果未注册，注册上宝宝树的数据
                                callbackInner(null, user);
                            }
                            else {
                                if (objData.error == 41) {
                                    // 密码不匹配
                                    logger.error("原密码错误");
                                    callbackInner({status: 0, message: "原密码错误"});
                                } else if (objData.error == 2) {
                                    logger.error("宝宝树无用户数据");
                                    callbackInner({status: 0, message: "数据异常,为了您的密码安全，请退出重新登录后再进行密码修改!"});
                                } else {
                                    appService.getErrorMsg(objData.error, function(msg){
                                        logger.error(data+"," + msg);
                                        callbackInner({status: 0, message: "网络异常"});
                                    });
                                }

                            }
                        } else {
                            logger.error(data);
                            callbackInner({status:0,message:"网络异常"});
                        }
                    }).on('error', function (err) {
                        logger.error(err);
                        callbackInner(err);
                    });
                });
            } else {
                /*  宝宝树66小区二期拼团    add  修改本地密码 luolh  20170915   end   */
                // 未联通用户，无法修改，重新退出
                //logger.error("未联通用户，无法修改，重新退出");
                //callbackInner({status:0, message:"此用户数据异常,请去宝宝树APP修改此密码!"});
                if (user.userPassword != md5(input.oldPassword)) {
                    var msg = {
                        "message": "原密码错误"
                    };
                    callbackInner(msg, null);
                } else {
                    callbackInner(null, user);
                }
                /*  宝宝树66小区二期拼团    add  修改本地密码 luolh  20170915   end   */
            }
            // if (user.userPassword != md5(input.oldPassword)) {
            //     var msg = {
            //         "message": "原密码错误"
            //     };
            //     callbackInner(msg, null);
            // } else {
            //     callbackInner(null, user);
            // }
            /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   end   */
        },
        //用新密码替换旧密码
        function (user, callbackInner) {
            /*  宝宝树66小区二期拼团    add  修改本地密码 luolh  20170915   end   */
            if (user.encUserId != null && user.encUserId != "") {
                /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   start   */
                // Users.update({_id: id}, {'userPassword': md5(input.newPassword)}, callbackInner);
                appService.updateSsoPassword(user.encUserId, input.newPassword, clientIp, function (err, updRemoteResult) { // 新
                // appService.updateSsoPassword(user.encUserId, input.newPassword, function (err, updRemoteResult) { // 旧
                    logger.debug(updRemoteResult);
                    if (err) {
                        // 修正失败
                        logger.error(err);
                        callbackInner(err);
                    } else {
                        // 修正成功,修正66密码
                        Users.update({_id: id}, {userPassword: ''}, function (err, updLocResult) {
                            logger.debug(updLocResult);
                            if (err) {
                                // 修正本地失败
                                logger.error(err);
                                callbackInner(err);
                            } else {
                                // 修正本地成功,修正宝宝树密码
                                callbackInner();
                            }
                        });
                    }
                });
                /*  宝宝树66小区二期拼团    add  注册极验证 luolh  20170824   end   */
            } else {
                // 如果没有联通，无ecnuserid,修改本地密码
                // 修正成功,修正66密码
                Users.update({_id: id}, {userPassword: md5(input.newPassword)}, function (err, updLocResult) {
                    logger.debug(updLocResult);
                    if (err) {
                        // 修正本地失败
                        logger.error(err);
                        callbackInner(err);
                    } else {
                        // 修正本地成功,修正宝宝树密码
                        callbackInner();
                    }
                });
            }
            /*  宝宝树66小区二期拼团    add  修改本地密码 luolh  20170915   end   */
        }
    ], callback);

};

exports.updateService = function (token, input, vcode, callback) {

    logger.info(input);

    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null)
        } else {
            var id = user._id;
            async.series([

                //更新用户的profile
                function (callbackInner) {
                    delete input.authenticationStatus;

                    if (input.nickName != null) {
                        input.pinyin = pinyin(input.nickName, {style: pinyin.STYLE_NORMAL}).join('').toLowerCase();
                        input.pinyinShort = pinyin(input.nickName, {style: pinyin.STYLE_FIRST_LETTER}).join('');
                        input.pinyinSort = input.pinyin + '_' + (new Date()).getTime()
                    }
                    /*  宝宝树66小区二次改造    add  查询用户nickName修改次数（只允许修改一次） luolh  20170720   start   */
                    /*  宝宝树66小区二次改造    add  需求变更，nickName不需修改 luolh  20170722   start   */
                    // Users.findOne({_id: id}, function (err, oldUser) {
                    //         if (err) {
                    //             callbackInner(err, null);
                    //         } else if (oldUser.nickName != input.nickName && oldUser.nickUpCnt != null && oldUser.nickUpCnt >= 1) {
                    //             callbackInner({"message":"昵称只能修改一次"}, null);
                    //         } else {
                    //             if (oldUser.nickName != input.nickName) {
                    //                 input.nickUpCnt = 1;
                    //             }
                    //             Users.update({_id: id},{$set:input}, callbackInner);
                    //         }
                    // });
                    Users.update({_id: id},{$set:input}, callbackInner);
                    /*  宝宝树66小区二次改造    add  需求变更，nickName不需修改 luolh  20170722   end   */
                    /*  宝宝树66小区二次改造    add   luolh  20170720   end   */

                },
                function (callbackInner) {
                    if (user.community != null) {
                        userCommunity.findOne({user: id, community: user.community._id}, function (err, result) {
                            if (result == null) {
                                var temp = new userCommunity();
                                temp.user = id;
                                temp.community = user.community._id;
                                if (input.roomUnit != null)
                                    temp.roomUnit = input.roomUnit;
                                if (input.roomNumber != null)
                                    temp.roomNumber = input.roomNumber;
                                temp.save(callbackInner)
                            } else {
                                var data = {};
                                if (input.roomUnit != null)
                                    data['roomUnit'] = input.roomUnit;
                                if (input.roomNumber != null)
                                    data['roomNumber'] = input.roomNumber;
                                userCommunity.update({user: id, community: user.community._id}, data, callbackInner)
                            }
                        })
                    } else {
                        callbackInner(null, null);
                    }
                },
                function (callbackInner) {
                    if (vcode < 300000 && input.homeTown != null) {
                        var ids = [];
                        for (var key in input.homeTown) {
                            ids.push(input.homeTown[key]);
                        }

                        RegionUser.find({_id: {$in: ids}}, function (err, rUresult) {
                            if (rUresult != null && rUresult.length == 2) {
                                var cityName = '';
                                var provinceName = '';

                                rUresult.forEach(function (item) {
                                    if (item.type == 'province') {
                                        provinceName = item.name;
                                    } else if (item.type == 'city') {
                                        cityName = item.name;
                                    }
                                });

                                Region.find({
                                    $or: [{type: 'province', name: provinceName}, {
                                        type: 'city',
                                        name: new RegExp(cityName)
                                    }]
                                }, function (err, nResult) {
                                    if (nResult != null && nResult.length == 2) {
                                        var homeTown = {};
                                        nResult.forEach(function (item) {
                                            if (item.type == 'province') {
                                                homeTown.province = item._id;
                                            } else if (item.type == 'city') {
                                                homeTown.city = item._id;
                                            }
                                        });
                                        Users.update({_id: id}, {homeTown: homeTown}).exec();
                                    } else {
                                        Users.update({_id: id}, {$unset: {homeTown: ''}}).exec();
                                    }
                                })
                            } else {
                                Users.update({_id: id}, {$unset: {homeTown: ''}}).exec();
                            }
                        });
                    }
                    callbackInner();
                },
                //更新最后修改日期
                function (callbackInner) {
                    Users.update({_id: id}, {dateLastModified: new Date()}, callbackInner);
                }
            ], callback);
        }
    });
};


/**
 * 上传用户头像，对图像始终是更新操作
 */
exports.setImagesToUser = function (id, images, callback) {
    Users.update({_id: id}, {$set: {'images': images}}, callback);
};


/**
 * 设置用户小区信息
 * @param community
 * @param callback
 */
exports.setUserCommunityService = function (token, community, callback) {
    Users.findOne({_id: toolUtil.getUserObjIdByToken(token)}, '_id community').populate('community', '_id communityName').exec(function (err, user) {
        if (user.community != null && user.community.communityName == community.name) {
            callback(null, user.community._id);
        } else {
            async.waterfall([
                function (callbackInner) {
                    if (user.community == null) {
                        callbackInner(null, null);
                    } else {
                        Community.findOne({_id: user.community._id}, 'chatGroupId', function (err, result) {
                            if (result != null && result.chatGroupId != null) {
                                toolUtil.getAndCacheHuanXinToken(function (err, token) {
                                    var args = {
                                        data: {},
                                        headers: {
                                            "Content-Type": "application/json",
                                            "Authorization": "Bearer " + token
                                        }
                                    };
                                    restClient.delete("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + result.chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                        logger.info(data);
                                        if (response.statusCode == 200) {
                                            logger.info('Success to delete user from community group')
                                        }
                                    })
                                });
                            }
                            callbackInner(null, null);
                            redisClient.srem('u:c:' + user.community._id, user._id);
                        });
                    }
                },
                function (res, callbackInner) {
                    Community.findOne({communityName: community.name}, {}, function (err, result) {
                        callbackInner(null, result)
                    })
                },
                function (result, callbackInner) {
                    if (result == null) {
                        var temp = new Community();
                        temp.communityName = community.name;
                        temp.communityAddress = community.address;
                        temp.location.latitude = community.location.lat;
                        temp.location.longitude = community.location.lng;
                        temp.save();
                    }
                    callbackInner(null, null);
                },
                function (result, callbackInner) {
                    Community.findOne({communityName: community.name}, {}, function (err, result) {
                        userAuthentication.findOne({
                            user: user._id,
                            community: result._doc._id
                        }, 'status', function (err, re) {
                            if (re != null && re.status) {
                                Users.update({_id: user._id}, {'authenticationStatus': true}, callbackInner);
                            } else {
                                Users.update({_id: user._id}, {'authenticationStatus': false}, callbackInner);
                            }
                        });
                        callbackInner(null, result)
                    })
                },
                function (result, callbackInner) {
                    var temp = {
                        'community': result._doc._id
                    };
                    //userService.updateService(id,temp,callbackInner);
                    Users.update({_id: user._id}, temp, function (err, result) {
                        callbackInner(err, temp.community)
                    });

                    redisClient.sadd('u:c:' + temp.community, user._id);

                    if (result.chatGroupId == null) {
                        toolUtil.getAndCacheHuanXinToken(function (err, token) {
                            var args = {
                                data: {
                                    "groupname": result.communityName + '群聊大厅', //群组名称, 此属性为必须的
                                    "desc": result.communityName, //群组描述, 此属性为必须的
                                    "public": true, //是否是公开群, 此属性为必须的
                                    "maxusers": 2000, //群组成员最大数(包括群主), 值为数值类型,默认值200,此属性为可选的
                                    "approval": false, //加入公开群是否需要批准, 没有这个属性的话默认是true（不需要群主批准，直接加入）, 此属性为可选的
                                    "owner": '66customerService',//群组的管理员, 此属性为必须的
                                    "members": [user.huanxinUserName]
                                },
                                headers: {
                                    "Content-Type": "application/json",
                                    "Authorization": "Bearer " + token
                                }
                            };
                            restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups", args, function (data, response) {
                                if (response.statusCode == 200) {
                                    if (data.data.groupid != null) {
                                        result.chatGroupId = data.data.groupid;
                                        result.save();
                                    }
                                }
                            }).on('error', function (err) {
                                logger.error('create community chat group' + err.message);
                            });
                        });
                    } else {
                        toolUtil.getAndCacheHuanXinToken(function (err, token) {
                            var args = {
                                data: {},
                                headers: {
                                    "Content-Type": "application/json",
                                    "Authorization": "Bearer " + token
                                }
                            };
                            restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + result.chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                if (response.statusCode == 200) {
                                    logger.info("Success to join community group");
                                }

                            }).on('error', function (err) {
                                logger.error('doRegisterService' + err.message);
                            });
                        });
                    }
                }
            ], callback)
        }
    })
};

/**
 * 设置用户小区     1.1.2
 * @param token
 * @param communityId
 * @param way
 * @param callback
 */
exports.setUserCommunityNewService = function (token, communityId, way, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null);
        } else {

            var chatGroupId;
            var community;
            if (user.community && user.community._id == communityId) {

                Community.find({_id: user.community._id}, 'chatGroupId communityName communityName_en_US pinyin communityAddress unitSwitch communityLogo isInit', function (err, result) {
                    // result.map(function(c) {
                    //     c._doc.communityName_en_US = (c.pinyin) ?
                    //         c.pinyin.toUpperCase() : pinyin(c.communityName, {style: pinyin.STYLE_NORMAL}).join('').toUpperCase();
                    // });
                    callback(err, result)
                })
            } else {
                async.series([
                    function (callbackInner) {
                        Community.findOne({_id: communityId}, '_id chatGroupId communityName communityName_en_US pinyin communityAddress unitSwitch communityLogo isInit cityId', function (err, result) {
                            if (result == null) {
                                var msg = {
                                    message: '小区不存在'
                                };
                                callbackInner(msg, null)
                            } else {

                                // result._doc.communityName_en_US = (result.pinyin) ?
                                //     result.pinyin.toUpperCase() : pinyin(result.communityName, {style: pinyin.STYLE_NORMAL}).join('').toUpperCase();

                                chatGroupId = result.chatGroupId;
                                community = result;
                                callbackInner(err, result);
                            }
                        });
                    },
                    function (callbackInner) {                                                    //更换小区  城市
                        Users.update({_id: user._id}, {
                            cityId: community.cityId,
                            community: communityId,
                            communityWay: way
                        }, callbackInner);

                        redisClient.sadd('u:c:' + communityId, user._id);
                        redisClient.HDEL('app:community:peopleNum', communityId);
                    },
                    function (callbackInner) {                                                     //退群
                        if (user.community != null) {
                            Community.findOne({_id: user.community._id}, 'chatGroupId', function (err, result) {
                                if (result != null && result.chatGroupId != null && user.huanxinUserName != '66customerservice') {
                                }
                                callbackInner(null, null);
                                redisClient.srem('u:c:' + user.community._id, user._id);
                                redisClient.HDEL('app:community:peopleNum', user.community._id);
                            });
                        } else {

                            callbackInner();
                        }
                    },
                    function (callbackInner) {
                        if (chatGroupId != null && user.huanxinUserName != '66customerservice') {
                        }
                        callbackInner(null, null);
                    },
                    function (callbackInner) {
                        userAuthentication.findOne({
                            user: user._id,
                            community: communityId,
                            isValid: true
                        }, 'status', function (err, re) {
                            if (re != null && re.status) {
                                Users.update({_id: user._id}, {'authenticationStatus': true}, callbackInner);
                            } else {
                                Users.update({_id: user._id}, {'authenticationStatus': false}, callbackInner);
                            }
                        });
                    },
                    function (callbackInner) {
                        userCommunity.findOne({
                            user: user._id,
                            community: communityId,
                            type: 1
                        }, 'roomUnit roomNumber userRole', function (err, result) {
                            var data = {};
                            if (result != null) {
                                if (result.roomUnit != null)
                                    data['roomUnit'] = result.roomUnit;
                                if (result.roomNumber != null)
                                    data['roomNumber'] = result.roomNumber;
                                if (result.userRole != null)
                                    data['userRole'] = result.userRole;
                            } else {
                                if (user.community == null) {
                                    var temp = new userCommunity();
                                    temp.user = user._id;
                                    temp.community = communityId;
                                    temp.save()
                                }
                            }
                            Users.update({_id: user._id}, data, function () {
                                callbackInner(null, user.community);
                            });
                        });
                    }
                ], callback)
            }
        }
    });
};

exports.addCommunityService = function (token, community, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {
            if (community == user.community._id) {
                return callback({message: '已在当前小区'})
            }

            Community.findOne({_id: community}, 'communityName isInit cityId', function (err, result) {
                if (result == null) return callback({message: '小区不存在'});

                userCommunity.count({user: user._id}, function (err, count) {
                    if (count >= USER_COMMUNITY) {
                        return callback({message: '达到上限'})
                    }

                    async.series([
                        function (callbackInner) {
                            //Users.update({_id: user._id}, {community: community, userRole: []}, callbackInner);
                            callbackInner();
                        },
                        function (callbackInner) {
                            userCommunity.findOne({
                                user: user._id,
                                community: user.community._id
                            }, function (err, result) {
                                if (result == null) {
                                    var temp = new userCommunity();
                                    temp.user = user._id;
                                    temp.community = user.community._id;
                                    temp.userRole = user.userRole;
                                    temp.save(callbackInner);
                                } else {
                                    callbackInner();
                                }
                            })
                        },
                        function (callbackInner) {
                            var temp = new userCommunity();
                            temp.user = user._id;
                            temp.type = 2;
                            temp.community = community;
                            temp.save(callbackInner)
                        },
                        function (callbackInner) {
                            //userAuthentication.findOne({
                            //    user: user._id,
                            //    community: community,
                            //    isValid: true
                            //}, 'status', function (err, re) {
                            //    if (re != null && re.status) {
                            //        Users.update({_id: user._id}, {'authenticationStatus': true}, callbackInner);
                            //    } else {
                            //        Users.update({_id: user._id}, {'authenticationStatus': false}, callbackInner);
                            //    }
                            //});
                            callbackInner();
                        },
                        function (callbackInner) {
                            //toolUtil.setUserByToken(token);
                            Group.findOne({
                                members: {$elemMatch: {user: user._id, status: 1}}
                            }, callbackInner)
                        }
                    ], function (err, res) {
                        if (res[4] != null) {
                            result._doc['groupId'] = res[4]._id;
                        }

                        callback(null, result);
                    })
                })
            });
        }
    })
};

exports.getUserCommunityListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            return callback(err)
        }

        userCommunity.findOne({
            user: user._id,
            type: 2,
            community: {$ne: user.community._id}
        }, 'community').populate('community', 'communityName cityId').exec(function (err, result) {
            if (err) return callback(err);

            var data = {
                isAdd: result == null
            };
            if (result != null) {
                data.parentCommunity = result.community._id;
                data.parentCommunityName = result.community.communityName;
                data.parentCity = result.community.cityId;
            }

            communityApplication.find({
                isValid: true,
                user: user._id,
                type: 2
            }, 'communityName status').sort('-dateCreated').limit(1).exec(function (err, apply) {
                if (apply != null && apply.length == 1) {
                    data.applyStatus = apply[0].status
                }
                callback(null, data)
            });
        })
    })
};
/*  宝宝树66小区二次改造    add  小区切换 luolh  20170803   start   */
exports.getAmbassadorCommunityListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            return callback(err)
        }
        // 本小区取得
        Community.findOne({_id: user.community._id}).exec(function (err, comm) {
            if (err) return callback(err);
            if (comm == null) {
                // 如果无此社区，社区异常
                logger.error("社区异常");
                return callback({message:"社区异常"});
            }
            // 取得大使管理小区（非本小区）
            AmbassadorCommunity.find({
                user: user._id,
                isValid: true
            }).populate('community').sort({dateCreated : -1}).exec(function (err, abmCommList) {
                if (err) return callback(err);

                var resultList = [];
                resultList.push(comm);
                logger.debug("abm:" + abmCommList);
                if (abmCommList != null && abmCommList.length > 0){
                    for (var i =0; i < abmCommList.length; i++) {
                        resultList.push(abmCommList[i].community);
                    }
                }
                var result = {communityList : resultList};
                callback(null, result);
            });
        });
    })
};
/*  宝宝树66小区二次改造    add  小区切换 luolh  20170803   end   */

exports.backSetUserCommunityService = function (communityId, userId, callback) {
    logger.debug('backSetUserCommunityService start...');
    var community, user;
    async.series([
        function (callbackInner) {
            Community.findOne({_id: communityId}, '_id chatGroupId communityName communityAddress unitSwitch communityLogo isInit cityId', function (err, result) {
                if (result == null) {
                    var msg = {
                        message: '小区不存在'
                    };
                    callbackInner(msg, null)
                } else {
                    community = result;
                    callbackInner(err, result);
                }
            });
        },
        function (callbackInner) {
            Users.findOne({_id: userId}, 'community', function (err, result) {
                user = result;
                callbackInner(err, result.community)
            })
        },
        function (callbackInner) {                                                    //更换小区
            logger.debug('userCommunity.findOne start...');
            userCommunity.findOne({
                user: userId,
                community: communityId,
                type: 1
            }, 'roomUnit roomNumber userRole', function (err, result) {
                var data = {};
                if (result != null) {
                    logger.debug('result != null...');
                    if (result.roomUnit != null)
                        data['roomUnit'] = result.roomUnit;
                    if (result.roomNumber != null)
                        data['roomNumber'] = result.roomNumber;
                    if (result.userRole != null)
                        data['userRole'] = result.userRole;
                } else {
                    logger.debug('result == null...');
                    var temp = new userCommunity();
                    temp.user = user._id;
                    temp.community = communityId;
                    temp.save();
                    logger.debug('userCommunity.save end...' + userId + '@' + communityId);
                    /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170905   start   */
                    // 只有insert数据了，才能remove
                    userCommunity.remove({user: userId, community: user.community, type: 1}).exec();
                    logger.debug('userCommunity.remove end...' + userId + '@' + user.community);
                }

                // userCommunity.remove({user: userId, community: user.community, type: 1}).exec();
                /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170905   end   */


                Users.update({_id: userId}, data, function () {
                });

                /*  宝宝树66小区二次改造    add   chenf  20170822   start   用户修改小区*/
                // 检索该用户的申请大使成功的申请信息
                RoleApply.findOne({user: userId,status : 1,community:user.community},function(err,result)
                {
                    if(err)
                    {
                        logger.error(err.message);
                        callbackInner(err, result);
                    }
                    else if(result!=null)
                    {
                        // 将该用户的申请大使成功的申请信息修改为已拒绝状态
                        RoleApply.update({user: userId,status : 1}, {status:-1},{ multi: true },function(err,result)
                        {
                            if(err)
                            {
                                logger.error(err.message);
                                callbackInner(err, result);
                            }
                            else if(result!=null)
                            {
                                // 将该用户管理小区的权限取消
                                ambassadorCommunity.update({user: userId},{isValid:false},{ multi: true }, callbackInner);
                            }
                        })
                    }else if(result==null)
                    {
                        // 将该用户的申请大使的申请信息修改为已拒绝状态
                        RoleApply.update({user: userId,status : 0}, {status:-1},{ multi: true },function(err,result)
                        {
                            // 将该用户管理小区的权限取消
                            ambassadorCommunity.update({user: userId},{isValid:false},{ multi: true }, callbackInner);
                        })
                    }
                });
                /*  宝宝树66小区二次改造    add   chenf  20170822   end   */
            });

            Users.update({_id: userId}, {community: communityId, cityId: community.cityId}, callbackInner);

        }
    ], callback)
};

exports.backInitCommunityService = function (communityId, callback) {
    Community.findOne({_id: communityId}, 'isInit', function (err, result) {
        if (result != null && !result.isInit) {
            exports.initCommunityQuestionService(communityId);
        }
        callback();
    })
};

/**
 * userService.js
 *根据用户名或邮箱或手机号查找用户ID
 *author：chenjinzhuan
 * */
exports.getUserIdService = function (username, callback) {
    async.series([
        //查找用户名中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({userName: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找email中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({email: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找手机号中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({mobilePhone: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找 wechatId 中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({wechatId: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        }
    ], function (err, results) {
        //仅仅返回结果数组中非空的元素
        async.series([
            function () {
                for (var i = 0; i < results.length; i++) {
                    if (results[i] != null) {
                        callback(null, results[i].userId);
                    }
                }
            }

        ], callback);

    });

};

/**
 * userService.js
 *获取通讯录
 * @param id
 * @param callback
 *author：chenjinzhuan
 * */
exports.getContactListService = function (id, callback) {
    Users.findOne({_id: id}, function (err, user) {
        if (err) {
            logger.error('Exception happened in getContactListService...!');
            return callback('err', null);
        } else if (user == null) {
            logger.error('user does not exist...!');
            return callback(err, null);
        } else {
            var contacts = [];
            var ids = user.contactBook;

            var ii = [];
            for (var i = 0; i < ids.length; i++) {
                ii[i] = i;
            }

            //对每一个id进行查找并处理
            async.forEachSeries(ii, function (i, callbackInner) {
                //需要populate某个属性时，必须将该属性添加到查找域中，如下的community
                Users.findOne({_id: ids[i]}, '_id nickName community huanxinUserName images')
                    .populate('community', 'communityName')
                    .exec(function (err, contact) {

                        if (err) {
                            logger.error('Exception happened in getContactListService......!');
                            return callbackInner(err, null);
                        } else if (contact == null) {
                            logger.error('Exception happened in getContactListService11......!');
                            return callbackInner(err, null);
                        } else {
                            var elem = {
                                objId: null,
                                nickName: null,
                                communityName: null,
                                huanxinUserName: null,
                                images: null
                            };
                            elem.objId = contact._id;
                            elem.nickName = contact.nickName;
                            elem.communityName = contact.communityName;
                            elem.huanxinUserName = contact.huanxinUserName;
                            elem.images = contact.images;
                            contacts[i] = elem;
                            //contacts = contact;
                            callbackInner();
                        }
                    });
            }, function () {
                return callback(null, contacts);
            });
        }
    });
};

/**
 * userService.js
 *添加到通讯录
 *author：chenjinzhuan
 * */
exports.addToContactListService = function (id, userName, userNameToAdd, callback) {
    //由于环信在当前用户添加好友时，在好友的好友列表中也会添加当前用户。所以为了和环信同步，需要在数据库中也相互添加好友
    async.waterfall([
        //通过好友用户名获取好友用户Id
        function (callbackInner) {
            userService.getUserIdService(userNameToAdd, function (err, idToAdd) {
                if (err) {
                    logger.debug('Exception happened in addToContactListService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to get the idToAdd...');
                    callbackInner(null, idToAdd);
                }
            });
        },
        //对当前用户添加好友
        function (idToAdd, callbackInner) {
            //根据用户id查找用户信息
            Users.findOne({_id: id}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in addToContactListService...!');
                    return callback(err);
                } else if (user == null) {
                    logger.error('addToContactListService: User does not exist...!');
                    return callback(err, null);
                } else {
                    logger.debug('user:' + user.contactBook);
                    //判断要添加的用户是否存在
                    for (var i = 0; i < user.contactBook.length; i++) {
                        if (idToAdd.toString() == user.contactBook[i]) {
                            logger.error('addToContactListService: User already exist...!');
                            return callback(err, null);
                        }
                    }

                    //给当前用户添加好友
                    user.contactBook.push(idToAdd);
                    user.save(function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 2....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 1...');
                            callbackInner(null, idToAdd);
                        }
                    });
                }
            });
        },
        //对好友添加当前用户
        function (idToAdd, callbackInner) {
            //根据好友id查找用户
            Users.findOne({_id: idToAdd}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in addToContactListService...!');
                    return callback(err);
                } else if (user == null) {
                    logger.error('addToContactListService: User does not exist...!');
                    return callback(err, null);
                } else {
                    //判断要添加的用户是否存在
                    for (var i = 0; i < user.contactBook.length; i++) {
                        if (id.toString() == user.contactBook[i]) {
                            logger.error('addToContactListService: User already exist...!');
                            return callback(err, null);
                        }
                    }

                    //对好友添加当前用户
                    var mongoose = require('mongoose');
                    var objId = mongoose.Types.ObjectId(id);
                    //var objId = mongoose.mongo.BSONPure.ObjectID.fromString(id);
                    user.contactBook.push(objId);
                    Users.update({_id: idToAdd}, {contactBook: user.contactBook}, function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 2...');
                            callbackInner(null, idToAdd);
                        }
                    });
                    //user.save(function (err) {
                    //    if (err) {
                    //        logger.debug('Exception happened in addToContactListService 3....');
                    //        return callback(err);
                    //    } else {
                    //        logger.debug('succeed to save the user 2...');
                    //        callbackInner(null, idToAdd);
                    //    }
                    //});
                }
            });
        },
        //在环信中添加好友
        function (callbackInner) {
            //环信添加好友开始
            var http = require('http');

            //获取环信token
            userService.getHuanxinTokenService(function (err, results) {
                if (err) {
                    logger.error('Exception happened when add to contactList 1...!');
                } else {
                    logger.debug('Set Token...!');
                    //var resultsParse = JSON.parse(results);
                    //var resultsParse = results;

                    //构造链接选项
                    var urlOpts = {
                        host: 'a1.easemob.com',
                        //path: '/easemob-demo/chatdemoui/users/'+userName+'/contacts/users/'+userNameToAdd,
                        path: '/66xiaoqu/' + huanxinEnv + '/users/' + userName + '/contacts/users/' + userNameToAdd,
                        port: '80',
                        method: 'POST',
                        headers: {
                            "Authorization": 'Bearer ' + results
                        }
                    };

                    //向环信提交请求
                    var request = http.request(urlOpts, function (response) {
                        response.on('data', function (chunk) {//请求成功的情况
                            logger.debug(chunk.toString());
                            return callback(null);
                        });
                    }).on('error', function (e) {//请求失败的情况
                        logger.debug('error:' + e.stack);
                        //删除在数据库通讯录中的用户好友
                        userService.RemoveFromContactListService(id, userName, userNameToAdd, function (err) {
                            if (err) {
                                logger.error(err.message);
                                logger.error('Exception happened when Remove to contactList in addToContactList...!');
                                return callback(err);
                            } else {
                                logger.debug('Remove to contactlist successfully in addToContactList...!');
                                return callback(err);
                            }
                        });
                    });
                    // write data to request body
                    //request.write(post_data + "\n");
                    request.end();
                }
            });

            //环信添加好友结束
        }
    ], callback);


};

/**
 * userService.js
 *从通讯录删除
 *author：chenjinzhuan
 * */
exports.RemoveFromContactListService = function (id, userName, userNameToRemove, callback) {
    //由于环信在当前用户删除好友时，在好友的好友列表中也会删除当前用户。所以为了和环信同步，需要在数据库中也相互删除好友
    async.waterfall([
        //通过好友用户名获取好友用户Id
        function (callbackInner) {
            userService.getUserIdService(userNameToRemove, function (err, idToRemove) {
                if (err) {
                    logger.debug('Exception happened in RemoveFromContactListService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to get the idToAdd...');
                    callbackInner(null, idToRemove);
                }
            });
        },
        //对当前用户删除好友
        function (idToRemove, callbackInner) {
            //根据用户id查找用户信息
            Users.findOne({_id: id}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in RemoveFromContactListService 2...!');
                } else if (user == null) {
                    logger.error('RemoveFromContactListService: User does not exist...!');
                    return callback(err);
                } else {
                    logger.debug('contactbook hello1:' + user.contactBook);
                    logger.debug('contactbook hello1:' + toString(user.contactBook[0]));
                    logger.debug('contactbook hello1:' + user.contactBook[1]);
                    logger.debug('contactbook hello1:' + user);
                    logger.debug('contactbook idtoremove:' + idToRemove);

                    for (var i = user.contactBook.length; i >= 0; i--) {
                        //if (/*idToRemove ==*/'54992018af970c5432de1b05' == user.contactBook[i]) {
                        if (idToRemove.toString() == user.contactBook[i]) {
                            user.contactBook.splice(i, 1);
                            logger.debug('contactbook:' + i + '...' + user.contactBook);
                        }
                    }
                    logger.debug('contactbook hello2:' + user.contactBook);

                    user.save(function (err) {
                        if (err) {
                            logger.debug('Exception happened in RemoveFromContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 1...');
                            callbackInner(null, idToRemove);
                        }
                    });
                }
            });
        },
        //对好友删除当前用户
        function (idToRemove, callbackInner) {
            //根据好友id查找用户
            Users.findOne({_id: idToRemove}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in RemoveFromContactListService 1...!');
                } else if (user == null) {
                    logger.error('RemoveFromContactListService: User does not exist...!');
                    return callback(err);
                } else {
                    logger.debug('contactbook hello1:' + user.contactBook);
                    logger.debug('contactbook hello1:' + toString(user.contactBook[0]));
                    logger.debug('contactbook hello1:' + user.contactBook[1]);
                    logger.debug('contactbook hello1:' + user);
                    logger.debug('contactbook idtoremove:' + idToRemove);

                    for (var i = user.contactBook.length; i >= 0; i--) {
                        //if (/*idToRemove ==*/'54992018af970c5432de1b05' == user.contactBook[i]) {
                        if (id.toString() == user.contactBook[i]) {
                            user.contactBook.splice(i, 1);
                            logger.debug('contactbook:' + i + '...' + user.contactBook);
                        }
                    }
                    logger.debug('contactbook hello2:' + user.contactBook);
                    Users.update({_id: idToRemove}, {contactBook: user.contactBook}, function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 2...');
                            callbackInner(null, idToRemove);
                        }
                    });
                    //user.save(function (err) {
                    //    if (err) {
                    //        logger.debug('Exception happened in RemoveFromContactListService 4....');
                    //        return callback(err);
                    //    } else {
                    //        logger.debug('succeed to save the user 2...');
                    //        callbackInner(null, idToRemove);
                    //    }
                    //});

                }
            });
        },
        //在环信中删除好友
        function (callbackInner) {
            //环信删除好友开始
            var http = require('http');

            //获取环信token
            userService.getHuanxinTokenService(function (err, results) {
                if (err) {
                    logger.error('Exception happened when remove contactList 1...!');
                    res.json(messageUtil.composeFailedMessage('Exception happened when remove contactList 5...!'));
                } else {
                    logger.debug('Set Token...!');
                    //var resultsParse = JSON.parse(results);
                    //var resultsParse = results;
                    logger.debug('results1: ' + results);
                    logger.debug('results: ' + results);

                    //构造链接选项
                    var urlOpts = {
                        host: 'a1.easemob.com',
                        //path: '/easemob-demo/chatdemoui/users/'+userName+'/contacts/users/'+userNameToAdd,
                        path: '/66xiaoqu/' + huanxinEnv + '/users/' + userNameToRemove + '/contacts/users/' + userName,
                        port: '80',
                        method: 'DELETE',
                        headers: {
                            "Authorization": 'Bearer ' + results
                        }
                    };

                    //向环信提交请求
                    var request = http.request(urlOpts, function (response) {
                        response.on('data', function (chunk) {//请求成功的情况
                            logger.debug(chunk.toString());
                            return callback(null);
                        });
                    }).on('error', function (e) {//请求失败的情况
                        logger.debug('error:' + e.stack);
                        //添加已经删除的数据库中的好友
                        userService.addToContactListService(id, idToRemove, function (err) {
                            if (err) {
                                logger.debug(err.message);
                                logger.error('Exception happened when add to contactList in RemoveFromContactList...!');
                                return callback(err);
                            } else {
                                logger.debug('Add to contactlist successfully in RemoveFromContactList...!');
                                return callback(err);
                            }
                        });
                    });
                    // write data to request body
                    //request.write(post_data + "\n");
                    request.end();
                }
            });

            //环信删除好友结束
        }
    ], callback);


};

/**
 * 关注
 */
exports.followupService = function (category, token, id, callback) {
    var userId = toolUtil.getUserObjIdByToken(token);
    logger.info('this category is ' + category);
    if (category == 'question') {
        UserFollowups.findOne({'user': userId, 'question': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.question = id;
                //temp.save(callback);
                saveUserFollowups(userId, id, temp, category, callback);
            } else {
                var msg = {
                    "message": '已经收藏过了'
                };
                callback(msg, null);
            }
        })
    } else if (category == 'activity') {
        UserFollowups.findOne({'user': userId, 'activity': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.activity = id;
                saveUserFollowups(userId, id, temp, category, callback);
                //temp.save(callback);
            } else {
                var msg = {
                    "message": '已经收藏过了'
                };
                callback(msg, null);
            }
        })
    } else if (category == 'user') {
        if (userId == id) {
            callback({"message": '不能关注自己'}, null);
        } else {
            UserFollowups.findOne({'user': userId, 'followUser': id}).exec(function (err, result) {
                if (result == null) {

                    var temp = new UserFollowups();
                    temp.category = category;
                    temp.user = toolUtil.getUserObjIdByToken(token);
                    temp.followUser = id;
                    saveUserFollowups(userId, id, temp, category, callback);
                    //temp.save(callback);
                } else {
                    var msg = {
                        "message": '已经关注过了'
                    };
                    callback(msg, null);
                }
            })
        }
    } else if (category == 'goods') {
        UserFollowups.findOne({'user': userId, 'goods': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.goods = id;
                saveUserFollowups(userId, id, temp, category, callback);
                //temp.save(callback);

                redisClient.HINCRBY('goods:' + id + ':detail', 'collectionNum', 1);

            } else {
                var msg = {
                    "message": '已经收藏过了'
                };
                callback(msg, null);
            }
        })
    } else {
        var msg = {
            "message": 'No such category '
        };
        callback(msg, null);
    }

};

/***
 *
 * @param userId    :  发起关注人
 * @param id        ： 关注的人
 * @param category  :  关注的类别
 * @param temp      :UserFollowups Model
 */
function saveUserFollowups(userId, id, temp, category, callback) {
    Users.findOne({_id: userId}, 'community').exec(function (err, result) {
        if (err)
            logger.warn(err);
        temp.fromCommunity = result.community; //用户关注时所在的小区

        //定义Model模版函数
        var findOneAndSaveTemplate = function (template, id, temp, callback) {
            template.findOne({_id: id}, 'community').exec(function (err, result) {
                if (err) logger.warn(err);
                //用户关注时 被关注用户所在的小区
                temp.toCommunity = result.community;
                logger.info('user_followups' + temp);
                temp.save(callback);
            })
        };
        //初始化模版模型
        var templateModel;

        switch (category) {
            case 'user':
                logger.info('this request model is question');
                templateModel = Users;
                break;
            case 'question':
                logger.info('this request model is question');
                templateModel = Question;
                break;
            case 'activity':
                logger.info('this request model is activity');
                templateModel = Activity;
                break;
            case 'goods':
                logger.info('this request model is goods');
                templateModel = Goods;
                break;
            default:
                logger.info('no exit this category ' + (category === 'activity'));
                break;
        }

        findOneAndSaveTemplate(templateModel, id, temp, callback);
        //if (category == 'user') {
        //Users.findOne({_id: id}, 'community').exec(function (err, result) {
        //    if (err) logger.warn(err);
        //    //用户关注时 被关注用户所在的小区
        //    temp.toCommunity = result.community;
        //    logger.info("toCommunity is :" + temp.toCommunity);
        //    logger.info('user_followups' + temp);
        //    temp.save(callback);
        //})
        //}

    });
}

/**
 * 取消关注
 */
exports.cancelFollowupService = function (category, token, id, callback) {
    if (category == 'question') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'question': id}).exec(callback);
    } else if (category == 'activity') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'activity': id}).exec(callback);
    } else if (category == 'user') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'followUser': id}).exec(callback);
    } else if (category == 'goods') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'goods': id}).exec(callback);

        redisClient.HINCRBY('goods:' + id + ':detail', 'collectionNum', -1);
    }
};

/**
 * 获取某类关注清单
 */
exports.getFollowupListService = function (page, category, token, callback) {
    var index = Number(page) * listPageSize;
    async.waterfall([
        function (callbackInner) {
            UserFollowups.find({
                'category': category,
                'user': toolUtil.getUserObjIdByToken(token)
            }, 'category question activity dateCreated').sort('-dateCreated').skip(index).limit(listPageSize).exec(function (err, results) {
                callbackInner(null, results);
            })
        },
        function (results, callbackInner) {
            if (results == undefined) {
                callbackInner(null, null);
            } else {
                var questionIdArray = new Array(results.length);

                for (var i = 0; i < results.length; i++) {
                    questionIdArray[i] = results[i].question;
                }

                var data = [];
                async.eachSeries(questionIdArray, function (id, callback) {
                    Question.findOne({
                        _id: id,
                        'isValid': true
                    }, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category status tag images.imageURL images._id replies pollOptions pollUserList dateCreated createdBy')
                        .populate('replies.repliedBy', '_id nickName images')
                        .populate('community', '_id communityName').populate('createdBy', '_id nickName images').populate('tag', 'category value _id').exec(function (err, question) {
                            if (question != null) {
                                if (question.category == 'poll') {
                                    var pollList = question.pollUserList;
                                    if (pollList != null && pollList.indexOf(toolUtil.getUserObjIdByToken(token)) != -1) {
                                        question._doc['voted'] = 'Yes'
                                    } else {
                                        question._doc['voted'] = 'No'
                                    }
                                    if (pollList != null) {
                                        question._doc['numberOfReplies'] = pollList.length;
                                    }

                                    question.browserCount = undefined;
                                } else {
                                    if (question.replies != null) {
                                        question._doc['numberOfReplies'] = question.replies.length;

                                        question.replies.forEach(function (reply) {
                                            if (reply.replyStatus == '已采纳') {
                                                question._doc['adoptedReply'] = reply;
                                            }
                                        })
                                    }

                                    if (question.browserCount == null) {
                                        question.browserCount = 0;
                                    }
                                    if (question.browserCount >= 200) {
                                        question._doc['hot'] = true;
                                    } else {
                                        question._doc['hot'] = false;
                                    }
                                }
                                if (question._doc.tag == null || question._doc.tag.length == 0) {
                                    question._doc.tag = undefined;
                                }
                                question._doc.replies = undefined;
                                question._doc.pollUserList = undefined;

                                data.push(question);
                            }
                            callback();
                        });
                }, function (err, results) {
                    if (err) {
                        var msg = {
                            "message": "get err"
                        };
                        callback(msg, null);
                    } else {
                        callback(null, data);
                    }
                });
            }
        }
    ], callback)
};

exports.getFollowupUsersService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            UserFollowups.find({
                'category': 'user',
                'user': user._id
            }, 'followUser dateCreated').sort('-dateCreated').exec(function (err, results) {
                var data = [];
                if (results != null) {
                    async.eachSeries(results, function (result, callback) {
                        Users.findOne({
                            _id: result.followUser,
                            community: user.community._id
                        }, '_id nickName images userType userPortrait authenticationStatus').populate('userPortrait', '_id value portraitURL')
                            .exec(function (err, user) {
                                if (user != null) {
                                    data.push(user);
                                }
                                callback();
                            })
                    }, function (err) {
                        callback(err, data);
                    })
                } else {
                    callback(err, null);
                }
            });
        }
    });
};

/**
 * 获取邻居列表
 */
exports.getNeighbourListService = function (page, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {

            var index = Number(page) * listPageSize;
            var communityId = user.community._id;
            var userId = user._id;
            Users.find({
                'community': communityId,
                '_id': {'$ne': userId},
                'messagePushSetting.showMeNearOn': true
            }, '_id nickName images huanxinUserName').skip(index).limit(listPageSize).exec(callback);
        }
    });
};

exports.findUserService = function (id, callback) {
    Users.findOne({$or: [{userName: id}, {email: id}, {mobilePhone: id}]}, callback);
};

exports.getUserProfileService = function (userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            async.series([
                function (callbackInner) {
                    Users.findOne({_id: userId}, 'huanxinUserName community userType', function (err, result) {
                        if (user.community._id != result.community && result.userType != 'service') {
                            var msg = {
                                "message": "不在同一个小区，无法查看资料"
                            };
                            callbackInner(msg, null);
                        } else {
                            callbackInner(err, result);
                        }
                    })
                },
                function (callbackInner) {
                    Users.findOne({_id: userId}, 'birthDate nickName images age huanxinUserName gender maritalStatus hasChildren apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county userType speciality userPortrait school authenticationStatus job roomUnit showUnit')
                        .populate('community', '_id communityName communityAddress').populate('userPortrait', 'portraitURL value')
                        .populate('homeTown.country', '_id name').populate('homeTown.province', '_id name')
                        .populate('homeTown.city', '_id name').populate('homeTown.county', '_id name')
                        .populate('hobbies', '_id value').exec(function (err, result) {
                            if (result.showUnit != null && !result.showUnit) {
                                result.roomUnit = undefined;
                            }
                            if (result.community == null) {
                                result.community = undefined;
                            }
                            result.showUnit = undefined;
                            callbackInner(err, result);
                        });
                },
                function (callbackInner) {

                    //Question.find({
                    //    $or: [{
                    //        'createdBy': userId,
                    //        'category': 'question',
                    //        'isValid': true
                    //    }, {
                    //        'replies.repliedBy': userId,
                    //        'category': 'question',
                    //        'isValid': true
                    //    }]
                    //}, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category tag images replies dateCreated createdBy')
                    //    .skip(0).limit(20).populate('tag', 'category value _id')
                    //    .populate('replies.repliedBy', '_id nickName images')
                    //    .populate('community', '_id communityName').populate('createdBy', '_id nickName images').sort('-dateCreated').exec(function (err, results) {
                    //        if (results == undefined || results == null) {
                    //            var msg = {
                    //                "message": 'get err'
                    //            };
                    //            callback(msg, null);
                    //        } else {
                    //            results.forEach(function (question) {
                    //                if (question.replies != null) {
                    //                    question._doc['numberOfReplies'] = question.replies.length;
                    //
                    //                    question.replies.forEach(function (reply) {
                    //                        if (reply.replyStatus == '已采纳') {
                    //                            question._doc['adoptedReply'] = reply;
                    //                        }
                    //                    });
                    //
                    //                    if (question._doc.adoptedReply == undefined && userId != question.createdBy._id) {
                    //                        question.replies.forEach(function (reply) {
                    //                            if (userId == reply.repliedBy._id) {
                    //                                question._doc['myReply'] = reply;
                    //                            }
                    //                        });
                    //                    }
                    //                }
                    //                if (question.browserCount == null) {
                    //                    question.browserCount = 0;
                    //                }
                    //
                    //                if (question._doc.tag == null || question._doc.tag.length == 0) {
                    //                    question._doc.tag = undefined;
                    //                }
                    //                question._doc.replies = undefined;
                    //            });
                    //            callbackInner(null, results);
                    //        }
                    //    })

                    var data = [];
                    callbackInner(null, data);
                },
                function (callbackInner) {
                    UserFollowups.findOne({'user': user._id, 'followUser': userId}, '', function (err, result) {
                        if (result == null) {
                            callbackInner(err, 'No');
                        } else {
                            callbackInner(err, 'Yes');
                        }
                    })
                }
                //function (callbackInner) {
                //    UserFollowups.find({
                //        'category': 'activity',
                //        'user': userId
                //    }, 'category question activity dateCreated', function (err, results) {
                //        var activityIdArray = new Array();
                //        if (results == undefined) {
                //        } else {
                //            for (var i = 0; i < results.length; i++) {
                //                activityIdArray[i] = results[i].activity;
                //            }
                //        }
                //
                //        Activity.find({$or: [{'createdBy': userId}, {_id: {$in: activityIdArray}}]}, '_id images activityName startDateTime endDateTime createdBy')
                //            .sort('-startDateTime').limit(2).exec(function (err, results) {
                //                if (results != null) {
                //                    results.forEach(function (activity) {
                //                        var start = moment(activity.startDateTime).format('MM月DD日 HH:mm');
                //                        var end = moment(activity.endDateTime).format('MM月DD日 HH:mm');
                //                        activity._doc['time'] = start + '—' + end;
                //
                //                        activity.startDateTime = undefined;
                //                        activity.endDateTime = undefined;
                //                    })
                //                }
                //                callbackInner(err, results);
                //            })
                //    })
                //}
            ], callback)
        }
    });
};

/**
 * 获取个人问题列表
 * @param page
 * @param userId
 * @param token
 * @param callback
 */
exports.getUserQuestionListService = function (page, userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            var index = Number(page) * listPageSize;

            Question.find({
                $or: [{
                    'createdBy': userId,
                    community: user.community._id,
                    'isValid': true
                }, {
                    'createdBy': {'$ne': userId},
                    'replies.repliedBy': userId,
                    community: user.community._id,
                    'isValid': true
                }]
            }, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category tag images replies dateCreated createdBy').skip(index).limit(listPageSize)
                .populate('tag', 'category value _id')
                .populate('replies.repliedBy', '_id nickName images')
                .populate('community', '_id communityName').populate('createdBy', '_id nickName images').sort('-dateCreated')
                .exec(function (err, results) {
                    if (results == undefined || results == null) {
                        var msg = {
                            "message": 'get err'
                        };
                        callback(msg, null);
                    } else {
                        results.forEach(function (question) {
                            if (question.replies != null) {
                                question._doc['numberOfReplies'] = question.replies.length;

                                question.replies.forEach(function (reply) {
                                    if (reply.replyStatus == '已采纳' && userId == question.createdBy._id) {
                                        question._doc['adoptedReply'] = reply;
                                    }
                                });

                                if (question._doc.adoptedReply == undefined && question.createdBy != null && userId != question.createdBy._id) {
                                    question.replies.forEach(function (reply) {
                                        if (userId == reply.repliedBy._id) {
                                            question._doc['myReply'] = reply;
                                        }
                                    });
                                }
                            }
                            if (question.browserCount == null) {
                                question.browserCount = 0;
                            }

                            if (question._doc.tag == null || question._doc.tag.length == 0) {
                                question._doc.tag = undefined;
                            }
                            question._doc.replies = undefined;
                        });
                        callback(null, results);
                    }
                });
        }
    });
};

exports.getUserQuestionListNewService = function (page, userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null)
        } else {
            page = Number(page);

            var index = page * listPageSize;
            var data = [];

            async.series([
                function (callbackInner) {
                    ugcIndex.find({community: user.community._id, createdBy: userId}).sort({
                        dateCreated: -1
                    }).skip(index).limit(listPageSize)
                        .exec(function (err, result) {
                            if (result != null) {
                                async.each(result, function (ugc, callbackInner) {
                                    if (ugc.category == 'neighbourActivity') {
                                        neighbourActivity.findOne({_id: ugc.ugcId}, '_id title replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy desc category dateCreated createdBy')
                                            .populate('tag', 'category value _id')
                                            .populate('replies.repliedBy', '_id nickName images')
                                            .populate('createdBy', '_id nickName images')
                                            .exec(function (err, activity) {
                                                if (activity != null) {

                                                    if (activity.replies != null) {
                                                        activity._doc['numberOfReplies'] = activity.replies.length;
                                                        activity.replies.forEach(function (reply) {
                                                            if (reply.replyStatus == '已采纳') {
                                                                activity._doc['adoptedReply'] = reply;
                                                            }
                                                        });
                                                    }
                                                    activity._doc.replies = undefined;
                                                    data.push(activity);
                                                }
                                                callbackInner(err);
                                            })
                                    } else {
                                        Question.findOne({
                                            _id: ugc.ugcId,
                                            'isValid': true
                                        }, '_id desc replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy category replies dateCreated createdBy')
                                            .populate('replies.repliedBy', '_id nickName images')
                                            .populate('createdBy', '_id nickName images').exec(function (err, question) {
                                                if (question != null) {
                                                    if (question.replies != null) {
                                                        question._doc['numberOfReplies'] = question.replies.length;
                                                        question.replies.forEach(function (reply) {
                                                            if (reply.replyStatus == '已采纳') {
                                                                question._doc['adoptedReply'] = reply;
                                                            }
                                                        });
                                                    }
                                                    question._doc.replies = undefined;

                                                    if (question._doc.adoptedReply != null && question._doc.adoptedReply.replyDesc.indexOf(atFlag) != -1) {
                                                        replyAt.findOne({replyId: question._doc.adoptedReply._id + ''}, function (err, at) {
                                                            if (at != null && at.uList != null) {
                                                                at.uList.forEach(function (temp, i) {
                                                                    question._doc.adoptedReply.replyDesc = question._doc.adoptedReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                                                                });
                                                            }
                                                            data.push(question);
                                                            callbackInner()
                                                        }).populate('uList', '_id nickName');
                                                    } else {
                                                        data.push(question);
                                                        callbackInner(err);
                                                    }
                                                } else {
                                                    callbackInner();
                                                }
                                            })
                                    }
                                }, function (err) {
                                    callbackInner(err, data);
                                })
                            } else {
                                callbackInner(err, data);
                            }
                        });
                }
                //function (callbackInner) {
                //    ugcReply.find({
                //        //$or: [{
                //        //    'createdBy': userId,
                //        //    community: user.community._id
                //        //}, {
                //        'createdBy': {'$ne': userId},
                //        'repliedBy': userId,
                //        ugcReply: {$not: {$size: 0}},
                //        community: user.community._id
                //        //}]
                //    }).sort('-dateCreated').exec(function (err, result) {
                //        if (result != null) {
                //            async.each(result, function (ugc, callbackInner) {
                //                if (ugc.category == 'neighbourActivity') {
                //                    neighbourActivity.findOne({_id: ugc.ugcId}, '_id title replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy desc category dateCreated createdBy')
                //                        .populate('tag', 'category value _id')
                //                        .populate('replies.repliedBy', '_id nickName images')
                //                        .populate('createdBy', '_id nickName images')
                //                        .exec(function (err, activity) {
                //                            if (activity != null) {
                //                                if (activity.replies != null) {
                //                                    activity._doc['numberOfReplies'] = activity.replies.length;
                //                                    activity.replies.forEach(function (reply) {
                //                                        if (reply.replyStatus == '已采纳') {
                //                                            activity._doc['adoptedReply'] = reply;
                //                                        }
                //                                    });
                //                                }
                //                                if (activity._doc.adoptedReply == undefined && activity.createdBy != null && userId != activity.createdBy._id) {
                //                                    activity.replies.forEach(function (reply) {
                //                                        if (userId == reply.repliedBy._id) {
                //                                            activity._doc['myReply'] = reply;
                //                                        }
                //                                    });
                //                                }
                //
                //                                activity._doc.replies = undefined;
                //
                //
                //                                if (activity._doc.myReply != null && activity._doc.myReply.replyDesc.indexOf(atFlag) != -1) {
                //                                    replyAt.findOne({replyId: activity._doc.myReply._id + ''}, function (err, at) {
                //                                        if (at != null && at.uList != null) {
                //                                            at.uList.forEach(function (temp, i) {
                //                                                activity._doc.myReply.replyDesc = activity._doc.myReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                //                                            });
                //                                        }
                //                                        data.push(activity);
                //                                        callbackInner()
                //                                    }).populate('uList', '_id nickName');
                //                                } else {
                //                                    data.push(activity);
                //                                    callbackInner(err);
                //                                }
                //                            } else {
                //                                callbackInner(err);
                //                            }
                //                        })
                //                } else {
                //                    Question.findOne({
                //                        _id: ugc.ugcId,
                //                        'isValid': true
                //                    }, '_id desc replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy category replies dateCreated createdBy')
                //                        .populate('replies.repliedBy', '_id nickName images')
                //                        .populate('createdBy', '_id nickName images').exec(function (err, question) {
                //                            if (question != null) {
                //                                if (question.replies != null) {
                //                                    question._doc['numberOfReplies'] = question.replies.length;
                //                                    question.replies.forEach(function (reply) {
                //                                        if (reply.replyStatus == '已采纳' && userId == question.createdBy._id) {
                //                                            question._doc['adoptedReply'] = reply;
                //                                        }
                //                                    });
                //
                //                                    if (question._doc.adoptedReply == undefined && question.createdBy != null && userId != question.createdBy._id) {
                //                                        question.replies.forEach(function (reply) {
                //                                            if (userId == reply.repliedBy._id) {
                //                                                question._doc['myReply'] = reply;
                //                                            }
                //                                        });
                //                                    }
                //                                }
                //
                //                                question._doc.replies = undefined;
                //
                //                                if (question._doc.myReply != null && question._doc.myReply.replyDesc.indexOf(atFlag) != -1) {
                //                                    replyAt.findOne({replyId: question._doc.myReply._id + ''}, function (err, at) {
                //                                        if (at != null && at.uList != null) {
                //                                            at.uList.forEach(function (temp, i) {
                //                                                question._doc.myReply.replyDesc = question._doc.myReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                //                                            });
                //                                        }
                //                                        data.push(question);
                //                                        callbackInner()
                //                                    }).populate('uList', '_id nickName');
                //                                } else {
                //                                    data.push(question);
                //                                    callbackInner(err);
                //                                }
                //                            } else {
                //                                callbackInner();
                //                            }
                //                        })
                //                }
                //            }, function (err) {
                //                callbackInner(err, data);
                //            })
                //        } else {
                //            callbackInner(null, []);
                //        }
                //    });
                //}
            ], function (err, result) {
                //data.sort(function (a, b) {
                //    return b.dateCreated - a.dateCreated;
                //});
                //var re = data.slice(page * listPageSize, (page + 1) * listPageSize);
                callback(err, data);
            });
        }
    })
};

/**
 * 首页数据service
 * @param token
 * @param callback
 */
exports.getHomePageService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            async.series([                       //modules
                function (callbackInner) {
                    appHomeModules.find({}, '-_id title imageURL displayOrder fieldName').sort('displayOrder').exec(callbackInner);
                },
                function (callbackInner) {       //new
                    var data = [];
                    freshNews.find({'community': user.community._id}, 'tag openType title bgColor url newsId createdBy').sort('-displayOrder').limit(3).exec(function (err, results) {
                        if (results != null && results.length > 0) {
                            results.forEach(function (news) {
                                var temp = {
                                    "tag": news.tag,
                                    "openType": news.openType,
                                    "type": news.tag,
                                    "bgColor": news.bgColor,
                                    "newsId": news.newsId,
                                    "createdBy": news.createdBy,
                                    "message": news.title,
                                    "url": news.url
                                };
                                data.push(temp);
                            })
                        }
                        callbackInner(err, data);
                    });


                    //var data = new Array();
                    //
                    //async.series([
                    //    function (callbackInner) {
                    //        Bulletins.findOne({
                    //            community: user.community._id,
                    //            isFresh: true
                    //        }, '_id title', function (err, result) {
                    //            if (result != null) {
                    //                var temp = {
                    //                    "tag": "公告",
                    //                    "openType": 1,
                    //                    "type": "公告",
                    //                    "bgColor": "#F7744A",
                    //                    "message": result.title,
                    //                    "newsId": result._id
                    //                };
                    //                data.push(temp);
                    //                callbackInner(err, null);
                    //            } else {
                    //                Bulletins.find({'community': user.community._id}, '_id title').sort('-dateCreated').limit(1).exec(function (err, results) {
                    //                    if (results != null && results.length > 0) {
                    //                        var result = results[0];
                    //                        var temp = {
                    //                            "openType": 1,
                    //                            "tag": "公告",
                    //                            "type": "公告",
                    //                            "bgColor": "#F7744A",
                    //                            "message": result.title,
                    //                            "newsId": result._id
                    //                        };
                    //                        data.push(temp);
                    //                    }
                    //                    callbackInner(err, null);
                    //                })
                    //            }
                    //        });
                    //    },
                    //    function (callbackInner) {
                    //        var date = (new Date).getTime() - 3 * 24 * 60 * 60 * 1000;
                    //        Users.find({
                    //            dateCreated: {$gte: new Date(date)},
                    //            'community': user.community._id,
                    //            authenticationStatus: true,
                    //            nickName: {$ne: '小6客服'}
                    //        }, '_id images nickName authenticationStatus userType').exec(function (err, results) {
                    //            if (results != null && results.length > 0) {
                    //                var num = toolUtil.getRandomNumArray(1, results.length);
                    //
                    //                var newUser = results[num[0]];
                    //                if (newUser.images != null && newUser.images.length > 0) {
                    //                    var temp = {
                    //                        "openType": 2,
                    //                        "tag": "新人",
                    //                        "type": "新人",
                    //                        "bgColor": "#FFCC00",
                    //                        "newsId": newUser._id,
                    //                        "message": newUser.nickName,
                    //                        "imageURL": newUser.images[0].imageURL
                    //                    };
                    //                    data.push(temp);
                    //
                    //                } else {
                    //                    var temp = {
                    //                        "openType": 2,
                    //                        "tag": "新人",
                    //                        "type": "新人",
                    //                        "bgColor": "#FFCC00",
                    //                        "newsId": newUser._id,
                    //                        "message": newUser.nickName
                    //                    };
                    //                    data.push(temp);
                    //                }
                    //                callbackInner(err, null);
                    //            } else {
                    //                Users.find({
                    //                    'community': user.community._id,
                    //                    authenticationStatus: true,
                    //                    nickName: {$ne: null}
                    //                }, '_id images nickName authenticationStatus userType').sort('-dateCreated').limit(20).exec(function (err, results) {
                    //                    if (results != null && results.length > 0) {
                    //
                    //                        var num = toolUtil.getRandomNumArray(1, results.length);
                    //                        var newUser = results[num[0]];
                    //                        if (newUser.images != null && newUser.images.length > 0) {
                    //                            var temp = {
                    //                                "openType": 2,
                    //                                "tag": "新人",
                    //                                "type": "新人",
                    //                                "bgColor": "#FFCC00",
                    //                                "newsId": newUser._id,
                    //                                "message": newUser.nickName,
                    //                                "imageURL": newUser.images[0].imageURL
                    //                            };
                    //                            data.push(temp);
                    //
                    //                        } else {
                    //                            var temp = {
                    //                                "openType": 2,
                    //                                "tag": "新人",
                    //                                "type": "新人",
                    //                                "bgColor": "#FFCC00",
                    //                                "newsId": newUser._id,
                    //                                "message": newUser.nickName
                    //                            };
                    //                            data.push(temp);
                    //                        }
                    //                    }
                    //                    callbackInner(err, null);
                    //                });
                    //            }
                    //        });
                    //    },
                    //    function (callbackInner) {
                    //        freshNews.find({'community': user.community._id}, 'tag openType title url newsId createdBy').sort('-dateCreated').limit(1).exec(function (err, results) {
                    //            if (results != null && results.length > 0) {
                    //                var news = results[0];
                    //                var temp = {
                    //                    "tag": news.tag,
                    //                    "openType": news.openType,
                    //                    "type": news.tag,
                    //                    "bgColor": "#7DB2EC",
                    //                    "newsId": news.newsId,
                    //                    "createdBy": news.createdBy,
                    //                    "message": news.title,
                    //                    "url": news.url
                    //                };
                    //                data.push(temp);
                    //
                    //            }
                    //            callbackInner(err, null);
                    //        });
                    //    }
                    //], function (err, result) {
                    //    callbackInner(null, data);
                    //});

                },
                function (callbackInner) {       //questions
                    questionService.getQuestionByAdoptedReplyService(user.community._id, function (err, results) {
                        callbackInner(err, results);
                    });
                },
                function (callbackInner) {
                    specialTopics.find({
                        community: user.community._id,
                        isValid: true
                    }, '_id title imageURL dateLastModified').sort('-dateCreated').limit(1)
                        .exec(function (err, results) {
                            var data = [];
                            if (results != null && results.length > 0) {
                                data.push(results[0])
                            }
                            data.forEach(function (topic) {
                                topic._doc['url'] = TopicsHost + '/' + topic._id + '.html'
                            });
                            callbackInner(null, data);
                        });
                },
                function (callbackInner) {

                    Users.find({
                        'userType': 'talent',
                        'community': user.community._id
                    }, '_id userPortrait nickName images speciality authenticationStatus').populate('userPortrait', 'value gender')
                        .exec(function (err, results) {
                            if (results != null) {
                                results.forEach(function (user) {
                                    if (user._doc.userPortrait != null) {
                                        user._doc['gender'] = user._doc.userPortrait.gender;
                                        user._doc.userPortrait = user._doc.userPortrait.value;
                                    }
                                    user._doc['tag'] = user.speciality;
                                    user.speciality = undefined;
                                });
                                if (results.length > 2) {
                                    var num = toolUtil.getRandomNumArray(2, results.length);
                                    var res = [];
                                    res.push(results[num[0]]);
                                    res.push(results[num[1]]);
                                    callbackInner(null, res);
                                } else {
                                    callbackInner(err, results);
                                }
                            } else {
                                callbackInner(null, null);
                            }
                        });

                    //QuestionReplyStatistics.find({'community': user.community._id}, '-_id user replyCount tag').populate('tag', 'value')
                    //    .populate('user', '_id nickName images userPortrait').sort('-replyCount').exec(function (err, results) {
                    //        if (results != null && results.length > 0) {
                    //            var newArray = [];
                    //            var provisionalTable = {};
                    //            for (var i = 0, item; results[i] != null && (item = results[i].user) != null; i++) {
                    //                if (!provisionalTable[item]) {
                    //                    newArray.push(results[i]);
                    //                    provisionalTable[item] = true;
                    //                }
                    //            }
                    //            results = newArray;
                    //            if (results.length > 2) {
                    //                results = results.splice(0, 2)
                    //            }
                    //            async.each(results, function (result, callback) {
                    //                userPortrait.findOne({_id: result.user.userPortrait}, 'value', function (err, por) {
                    //                    if (por != null) {
                    //                        result._doc.user._doc.userPortrait = por.value;
                    //                    }
                    //                    if (result.tag != null) {
                    //                        result._doc.user._doc['tag'] = result.tag.value;
                    //                    }
                    //                    result.replyCount = undefined;
                    //                    callback();
                    //                });
                    //            }, function (err) {
                    //                if (err) {
                    //                    callbackInner(err, null);
                    //                } else {
                    //                    callbackInner(null, results);
                    //                }
                    //            });
                    //        }
                    //    });
                }
            ], callback)
        }
    });
};


//1.5.0

exports.homePageBannerService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            BannerBind.find({community: user.community._id, type: 1}).sort('-displayOrder')
                .populate('bannerId', '_id contentId openType contentCreatedBy contentUrl imageURL')
                .exec(function (err, result) {
                    var data = [];
                    if (result != null) {
                        result.forEach(function (banner) {
                            data.push(banner.bannerId);
                        })
                    }
                    callback(null, data);
                })
        }
    })
};


exports.homePageFreshNewsService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            var data = [];
            BannerBind.find({community: user.community._id, type: 2}).sort('-displayOrder').limit(3)
                .populate('bannerId', '_id contentId openType contentCreatedBy contentUrl message tag bgColor')
                .exec(function (err, result) {
                    if (result != null && result.length > 0) {
                        result.sort(function (a, b) {
                            return b.dateCreated - a.dateCreated;
                        });
                        var sql = 'SELECT * FROM log_read WHERE user_id=? AND content_id =?';
                        mysqlUtil.query(sql, [user._id, result[0].bannerId.contentId + ''], function (err, log) {
                            result[0].isNew = log && log.length > 0 ? false : true;

                            result.sort(function (a, b) {
                                return b.displayOrder - a.displayOrder
                            });
                            result.forEach(function (news) {
                                var temp = news.bannerId;
                                temp._doc.isNew = news.isNew ? true : false;
                                data.push(temp);
                            });
                            callback(null, data);
                        })
                    } else {
                        callback(null, data);
                    }
                });
        }
    })
};


exports.homePageQuestionAndActivityService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            async.series([
                function (callbackInner) {
                    var questions = [];
                    //  宝宝树66小区二次改造   recommond失效 mod  luolh  20170724   start
                    // try {
                    //     restClient.get('http://' + RecommendHost + ':8003?recbyuid=' + user._id, function (data, response) {
                    //         if (response.statusCode == 200) {
                    //             data = JSON.parse(data);
                    //             var qIds = data.rec;
                    //             logger.info(qIds);
                    //
                    //             //var qIds = ['557a74e54cb63bb251ae5a7d', '557a78004cb63bb251ae5c99', '557a791f4cb63bb251ae5d81', '557a968e0a8045a0145c4819', '557a9c520a8045a0145c500c', '557a9f4b0a8045a0145c54a1']
                    //             async.eachSeries(qIds, function (id, callback1) {
                    //                 Question.findOne({_id: id}, function (err, question) {
                    //                     if (question != null) {
                    //                         var temp = {
                    //                             desc: question.desc,
                    //                             category: question.category,
                    //                             categoryTag: CategoryName[question.category],
                    //                             browserCount: toolUtil.transformNumber(question.browserCount),
                    //                             replyCount: toolUtil.transformNumber(question.replies.length),
                    //                             praiseCount: toolUtil.transformNumber(question.praiseCount),
                    //                             questionId: question._id,
                    //                             createdBy: question.createdBy
                    //                         };
                    //                         if (question.images != null && question.images.length > 0) {
                    //                             temp.pic = question.images[0].imageURL;
                    //                         }
                    //
                    //                         questionPraise.findOne({
                    //                             question: id,
                    //                             user: user._id
                    //                         }, function (err, result) {
                    //                             temp['isPraise'] = result != null;
                    //                             questions.push(temp);
                    //                             callback1()
                    //                         });
                    //
                    //                     } else {
                    //                         callback1()
                    //                     }
                    //                 })
                    //             }, function (err) {
                    //                 callbackInner(null, questions)
                    //             })
                    //         } else {
                    //             callbackInner(null, questions);
                    //         }
                    //     }).on('error', function (err) {
                    //         logger.error('get recommend error' + err.message);
                    //         callbackInner(null, questions);
                    //     });
                    // } catch (e) {
                    //     logger.error('get recommend error' + err.message);
                    //     callbackInner(null, questions);
                    // }
                    callbackInner(null, questions);
                    //  宝宝树66小区二次改造   recommond失效 mod  luolh  20170724   end
                },
                function (callbackInner) {
                    var activities = [];
                    neighbourActivity.find({
                        status: true,
                        isValid: true,
                        createdBy: {$ne: user._id},
                        'partake.user': {$ne: user._id},
                        $or: [{community: user.community._id}, {aroundCommunity: user.community._id}]
                    }).sort('-partakeNum').limit(6).exec(function (err, result) {

                        async.eachSeries(result, function (activity, c1) {
                            var temp = {
                                title: activity.title,
                                desc: activity.desc,
                                activityId: activity._id,
                                createdBy: activity.createdBy,
                                category: activity.category,
                                activityType: activity.activityType,
                                browserCount: toolUtil.transformNumber(activity.browserCount),
                                replyCount: toolUtil.transformNumber(activity.replies.length),
                                praiseCount: toolUtil.transformNumber(activity.praiseCount),
                                categoryTag: CategoryName[activity.category]
                            };
                            if (activity.images != null && activity.images.length > 0) {
                                temp.pic = activity.images[0].imageURL;
                            }

                            questionPraise.findOne({activity: activity._id, user: user._id}, function (err, result) {
                                temp['isPraise'] = result != null;
                                activities.push(temp);
                                c1();
                            });
                        }, function () {
                            callbackInner(null, activities);
                        })

                    })
                }
            ], callback)
        }
    })
};

exports.homePageTopicsService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            specialTopics.find({
                community: user.community._id,
                isValid: true
            }, '_id title imageURL dateLastModified').sort('-dateCreated').limit(2)
                .exec(function (err, results) {
                    results.forEach(function (topic) {
                        topic._doc['url'] = TopicsHost + '/' + topic._id + '.html'
                    });
                    callback(null, results);
                });
        }
    })
};

exports.userSignInService = function (token, callback) {

    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED);
        } else {
            if (!user.authenticationStatus) {
                callback({message: '非v用户无法签到'})
            } else {
                var key = 'app:signin:' + moment().format('YYYYMMDD');

                redisClient.SISMEMBER(key, token, function (err, result) {
                    if (result == 1) {
                        callback({message: '今天已经签到过了'})
                    } else {
                        callback();
                        redisClient.sadd(key, token);
                        redisClient.EXPIRE(key, 86400);
                    }
                })
            }
        }
    })
};


exports.randomSetCommunityService = function (token, callback) {
    var result = randomCommunities;

    var num = toolUtil.getRandomNumArray(1, result.length);

    var communityId = result[num[0]];

    exports.setUserCommunityNewService(token, communityId, 2, function (err, result) {
        if (err) {
            callback(err, null)
        } else {
            callback(null, result[0]);
        }
    })
};

exports.getUserQuestionStatisticsService = function (token, userId, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            var replyC = 0;
            async.series([
                function (callbackInner) {
                    ugcIndex.count({community: user.community._id, createdBy: userId}, callbackInner);
                },
                function (callbackInner) {
                    ugcReply.count({
                        community: user.community._id,
                        repliedBy: userId
                    }, function (err, count) {
                        replyC = count;
                        callbackInner(err, count)
                    });
                },
                function (callbackInner) {
                    AdoptedCount.findOne({user: userId, community: user.community._id}, function (err, result) {
                        if (result == null || replyC == 0) {
                            callbackInner(null, '0%')
                        } else {
                            var v = result.adoptedCount * 100 / replyC;
                            callbackInner(err, Math.round(v) + "%");
                        }
                    });
                },
                function (callbackInner) {
                    QuestionReplyPraise.count({'replyBy': userId}, callbackInner);
                }
            ], callback)
        }
    });
};

/**
 * 个人页数字1.6.0
 * @param token
 * @param callback
 */
exports.getMyAppStatisticsService = function (token, vcode, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {

            async.parallel([
                function (callbackInner) {
                    //var args = [redisKey.getUserDataStatisticKey(user._id), 'question', 'goods', 'questionReply'];
                    //redisClient.HMGET(args, callbackInner);
                    /*exports.getMyStatistics(user._id, callbackInner);*/

                    exports.getMyStatisticsNew(user._id, callbackInner);

                },
                function (callbackInner) {
                    //neighbourActivity.count({
                    //    isValid: true,
                    //    createdBy: user._id,
                    //    community: user.community._id
                    //}, callbackInner);
                    callbackInner();
                },
                function (callbackInner) {
                    scoreProxy.invoke('getScoreInfoByUid', [user._id + ''], function (err, result) {
                        if (err) {
                            callbackInner(null, '');
                        } else {
                            var data = JSON.parse(decodeURIComponent(result));
                            if (data.status != 0) {
                                logger.error('getUserScore----' + data.msg);
                                callbackInner(null, '');
                            } else {
                                callbackInner(null, data.data.scoreInfo.currentValue + '');
                            }
                        }
                    })
                },
                function (callbackInner) {              //关注
                    UserFollowups.find({category: 'user', user: user._id}, function (err, result) {
                        var count = 0;
                        callbackInner(null, result ? result.length : count);
                    }).populate('followUser', 'community')
                },
                function (callbackInner) {              //被关注
                    UserFollowups.find({category: 'user', followUser: user._id}, function (err, result) {
                        var count = 0;
                        callbackInner(null, result ? result.length : count);
                    }).populate('user', 'community')
                },
                function (callbackInner) {              //自运营
                    // if (user.userRole != null && user.userRole.indexOf(1) >= 0)
                    //     callbackInner(null, true);
                    // else
                    //     callbackInner(null, false);
                    Users.findOne({"_id": user._id}, {"userRole" : 1}, function (err, tempRole) {
                        if(tempRole.userRole != null && tempRole.userRole.indexOf(1) >= 0) {
                            callbackInner(null, true);
                        } else {
                            callbackInner(null, false);
                        }
                    });
                },
                function (callbackInner) {
                    var no = 0;

                    if (user.nickName != null && user.nickName != '') no++;
                    if (user.images != null && user.images.length > 0 && user.images[0].imageURL != 'http://66xiaoqu.babytreeimg.com/group1/M00/00/8A/wKgACFVArXSAGGyZAAAPgB4w4OI267.png') no++;
                    if (user.gender != null)no++;
                    if (user.birthDate != null) no++;
                    if (user.hobbies != null && user.hobbies.length > 0)no++;
                    if (user.roomUnit != null) no++;
                    if (user.roomNumber != null) no++;
                    if (user.homeTown != null) no++;

                    callbackInner(null, (no / 8).toFixed(2) * 100 + '');
                },
                function (callbackInner) {
                    UserTask.findOne({
                        user: user._id,
                        type: 'novice',
                        deadline: {$gt: new Date()}
                    }, 'name subTask', function (err, task) {
                        if (task != null) {
                            var i = 0;
                            task.subTask.forEach(function (sub) {
                                if (sub.status) {
                                    i++;
                                }
                            });
                            callbackInner(null, i == 0 ? 0 : (i / task.subTask.length).toFixed(2) * 100);
                        } else {
                            callbackInner();
                        }
                    })
                },
                function (callbackInner) {

                    var opt = {
                        isValid: true,
                        createdBy: user._id,
                        //community: user.community._id
                    };
                    if (vcode >= 200000) {
                        opt.category = {$ne: 'secondhand'}
                    }

                    Question.count(opt, callbackInner)
                },
                function (callbackInner) {
                    Group.findOne({
                        members: {$elemMatch: {user: user._id, status: 1}}
                    }, callbackInner)
                },
                /*  宝宝树66小区五期-小区大使申请   add  登陆极验证 guo.xiaomin  20171121   start   */
                function (callbackInner) {
                    // 当前小区是否有大使
                    Users.count({"community": user.community._id, "userRole": 4}, function (err, count) {
                        if(count > 0) {
                            callbackInner(null, true);
                        } else {
                            callbackInner(null, false);
                        }
                    });
                },
                function (callbackInner) {
                    var userId = user._id;
                    var communityId = user.community._id;
                    RoleApply.findOne({"user": userId, "community": communityId}, {"status" : 1, "cancelReason" : 1}).sort({"dateCreated": -1}).exec(function (err, temp) {
                        var tempObj = {};
                        if(temp) {
                            var status = temp.status;
                            var cancelReason = temp.cancelReason;
                            tempObj.status = status;
                            tempObj.cancelReason = cancelReason;
                            logger.debug("applyStatus..." + userId + "@" + communityId + "@" + status + "@" + cancelReason);
                            callbackInner(null, tempObj);
                        } else {
                            logger.debug("applyStatus..." + userId + "@" + communityId + "@" + "null");
                            callbackInner(null, {status: -9, cancelReason: null});
                        }
                    });
                }
                /*  宝宝树66小区五期-小区大使申请   add  登陆极验证 guo.xiaomin  20171121   end   */
            ], function (err, result) {
                var data = {
                    question: toolUtil.transformNumber(result[8], 'user'),
                    secondHand: result[0].goods,
                    reply: result[0].questionReply,
                    score: result[2],
                    activity: toolUtil.transformNumber(result[1], 'user'),
                    process: result[6],
                    follow: toolUtil.transformNumber(result[3], 'user'),
                    beFollowed: toolUtil.transformNumber(result[4], 'user'),
                    isModerator: result[5],
                    /*  宝宝树66小区五期   add  小区大使申请 guo.xiaomin  20171121   start   */
                    hasModerator: result[10],
                    applyStatus: result[11].status,
                    cancelReason: result[11].cancelReason,
                    /*  宝宝树66小区五期   add  小区大使申请 guo.xiaomin  20171121   end   */
                    opmUrl: opmUrl
                };
                /*  宝宝树66小区二次改造    mod   chenf  20170714   start   */
                /*if (result[7] != null && result[7] < 100) {*/
                if (result[7] != null) {
                /*  宝宝树66小区二次改造    mod   chenf  20170714   end   */
                    data.taskProgress = result[7];
                }
                if (result[9] != null) {
                    data.groupId = result[9]._id;
                }
                callback(err, data);
            });
        }
    })
};

exports.getMyStatistics = function (userId, callback) {
    userCommunity.find({user: userId}, function (err, result) {
        if (result == null) return callback({message: '获取个人信息出错'});
        var data = {
            question: 0,
            questionReply: 0,
            goods: 0
        };
        async.each(result, function (item, cb) {
            toolUtil.getUserStatistics(userId, item.community, function (err, value) {
                if (value != null) {
                    data.question += Number(value.question ? value.question : 0);
                    data.questionReply += Number(value.questionReply ? value.questionReply : 0);
                    data.goods += Number(value.goods ? value.goods : 0);
                }
                cb();
            })
        }, function (err) {
            data.question = toolUtil.transformNumber(data.question, 'user');
            data.questionReply = toolUtil.transformNumber(data.questionReply, 'user');
            data.goods = toolUtil.transformNumber(data.goods, 'user');
            callback(null, data)
        })
    });
};
/*  宝宝树66小区二次改造    add   chenf  20170822   start   */
exports.getMyStatisticsNew = function (userId, callback) {

    /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170906   start   */
    Users.find({'_id': userId}, function (err, result) { // 新
    // userCommunity.find({user: userId}, function (err, result) { // 旧
    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170906   start   */
        if (result == null) return callback({message: '获取个人信息出错'});

        var data = {
            question: 0,
            questionReply: 0,
            goods: 0
        };

        async.each(result, function (item, cb) {
            toolUtil.getUserStatisticsNew(userId,function (err, value) {
                if (value != null) {
                    data.question += Number(value.question ? value.question : 0);
                    data.questionReply += Number(value.questionReply ? value.questionReply : 0);
                    data.goods += Number(value.goods ? value.goods : 0);
                }
                cb();
            })
        }, function (err) {
            data.question = toolUtil.transformNumber(data.question, 'user');
            data.questionReply = toolUtil.transformNumber(data.questionReply, 'user');
            data.goods = toolUtil.transformNumber(data.goods, 'user');
            callback(null, data)
        })
    });
};
/*  宝宝树66小区二次改造    add   chenf  20170822   end   */
/**
 * 用户认证
 * @param token
 * @param req
 * @param callback
 */
exports.authenticateUserService = function (token, req, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            toolUtil.uploadImageService(null, null, req, function (err, images) {

                if (err) {
                    callback(err, null);
                } else {
                    if (images[0] == null) {
                        var msg = {
                            "message": "图片上传失败"
                        };
                        callback(msg, null);
                    } else {
                        logger.info(images);
                        var imageURL = images[1] != null ? images[1] : images[0];

                        userAuthentication.findOne({
                            user: user._id,
                            community: user.community._id,
                            isValid: true
                        }, '', function (err, result) {
                            if (result != null) {
                                result.imageURL = imageURL;
                                result.save(callback);
                            } else {
                                var temp = new userAuthentication();
                                temp.user = user._id;
                                temp.community = user.community._id;
                                temp.imageURL = imageURL;
                                temp.save(callback);
                            }
                        });
                    }
                }
            })
        }
    });
};

exports.authenticateUserByPromotionCodeService = function (code, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null)
        } else {
            promotionCode.findOne({
                code: code,
                expirationDate: {$gte: new Date()}
            }, function (err, result) {
                if (result == null) {
                    var message = {
                        message: '推广码错误，请重新输入'
                    };
                    callback(message, null)
                } else {
                    async.series([
                        function (callbackInner) {
                            Users.findOne({_id: user._id}, 'invitedBy mobilePhone').exec(function (err, user) {
                                if (user.mobilePhone != null && user.mobilePhone.indexOf('700700') == 0) {
                                    callbackInner({message: '测试账号，无法认证'})
                                } else {
                                    callbackInner(null, user.invitedBy);
                                }
                            });
                        },
                        function (callbackInner) {
                            userAuthentication.findOne({
                                user: user._id,
                                community: user.community._id,
                                isValid: true
                            }, '', function (err, result) {
                                if (result != null) {
                                    result.promotionCode = code;
                                    result.status = true;
                                    result.save(callbackInner);
                                } else {
                                    var temp = new userAuthentication();
                                    temp.user = user._id;
                                    temp.community = user.community._id;
                                    temp.promotionCode = code;
                                    temp.status = true;
                                    temp.save(callbackInner);
                                }
                            });
                        },
                        function (callbackInner) {
                            Users.update({_id: user._id}, {authenticationStatus: true}, callbackInner)
                        },
                        function (callbackInner) {
                            var data = [];
                            roleAction.find({role: 'vip'}).populate('action', 'tag').exec(function (err, results) {
                                if (results != null) {
                                    results.forEach(function (temp) {
                                        data.push(temp.action.tag);
                                    })
                                }
                                var res = {
                                    auth: data,
                                    vStatus: 1
                                };
                                callbackInner(err, res);
                            });
                        },
                        function (callbackInner) {
                            toolUtil.setUserByToken(token);
                            callbackInner(null, user.community._id);
                        },
                        function (callbackInner) {

                            var message = "你好，你的V认证已经通过，我们将为V用户提供更多，更好的服务，也让你在小区中更与众不同。";
                            toolUtil.pushCustomerServiceMessage(user, message);

                            callbackInner(null, null);
                        }
                    ], callback);
                }
            });
        }
    })
};
/**
 * 验证邀请码
 */
exports.validateInvitationCodeService = function (token, code, callback) {

    Users.findOne({invitationCode: code}, function (err, user) {
        if (user == null) {
            var msg = {
                message: '您输入的邀请码不存在，请重新输入'
            };
            callback(msg, null);
        } else if (user._id == token) {
            var msg = {
                message: '无法邀请自己'
            };
            callback(msg, null);
        } else {
            callback(null, user);
        }
    })
};

/**
 * 绑定邀请关系
 * @param token
 * @param user
 * @param invitationCode
 * @param deviceId
 */
exports.bindInvitationCodeService = function (token, user, invitationCode, deviceId) {
    Users.update({_id: token}, {invitedBy: user._id}).exec(function (err, result) {
        toolUtil.setUserByToken(token)
    });

    userInvitation.findOne({invitee: token}, function (err, result) {
        if (result == null) {
            var inv = new userInvitation();
            inv.invitee = token;
            inv.inviter = user._id;
            inv.save();
        } else {
            userInvitation.update({invitee: token}, {inviter: user._id}).exec();
        }
    });

    var temp = new deviceCodeBind();
    temp.invitationCode = invitationCode;
    temp.deviceId = deviceId;
    temp.user = token;
    temp.save();
};

exports.getUserAuthenticationStatusService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            userAuthentication.findOne({
                user: user._id,
                isValid: true,
                community: user.community._id
            }, 'status', function (err, result) {
                var data;
                if (result == null) {
                    data = {
                        "status": 0
                    }
                } else {
                    if (result.status) {
                        data = {
                            "status": 1
                        }
                    } else {
                        data = {
                            "status": 2
                        }
                    }
                }
                callback(err, data);
            })
        }
    })
};

exports.getUserInvitedCodeService = function (token, callback) {
    Users.findOne({_id: token}, 'invitedBy', function (err, result) {
        var invitedCode = '';
        if (result != null && result.invitedBy != null && result.invitedBy.invitationCode != null) {
            invitedCode = result.invitedBy.invitationCode;
        }
        callback(null, invitedCode);
    }).populate('invitedBy', 'invitationCode')
};


exports.getMyVoucherListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {
            var array = [];
            var userId = user._id + '';
            var sql = 'select * from voucher_type n,voucher_user_bind m where m.user_id=? and m.voucher_type_id=n.id';
            mysqlUtil.query(sql, userId, function (err, result) {
                console.log(result);
                if (result != null && result.length > 0) {
                    async.each(result, function (temp, callbackInner) {
                        if (temp.reward_source == 2) {
                            Users.findOne({_id: temp.invited_user}, function (err, invitedUser) {
                                var status = new Date().getTime() > temp.expire_time ? 2 : temp.is_use;
                                var data = {
                                    id: temp.id,
                                    voucherSource: '邀请邻居' + invitedUser.nickName,
                                    cardNo: temp.card_no,
                                    voucherName: temp.voucher_name,
                                    voucherValue: temp.voucher_val,
                                    startTime: moment(new Date(temp.create_time)).format('YYYY-MM-DD'),
                                    endTime: moment(new Date(temp.expire_time)).format('YYYY-MM-DD'),
                                    status: status                           //0,未消费；1，已消费；2，已过期
                                };
                                array.push(data);
                                callbackInner();
                            })
                        } else if (temp.reward_source == 1) {
                            var status = new Date().getTime() > temp.expire_time ? 2 : temp.is_use;
                            var data = {
                                id: temp.id,
                                voucherSource: 'V认证',
                                cardNo: temp.card_no,
                                voucherName: temp.voucher_name,
                                voucherValue: temp.voucher_val,
                                startTime: moment(new Date(temp.create_time)).format('YYYY-MM-DD'),
                                endTime: moment(new Date(temp.expire_time)).format('YYYY-MM-DD'),
                                status: status                           //0,未消费；1，已消费；2，已过期
                            };
                            array.push(data);
                            callbackInner();
                        } else {
                            callbackInner();
                        }
                    }, function (err) {

                        array.sort(function (a, b) {
                            if (a.status != 0 && b.status == 0) {
                                return 1;
                            } else {
                                return b.startTime - a.startTime;
                            }
                        });
                        callback(err, array);
                    })
                } else {
                    callback(null, array);
                }
            });
        }
    })
};

exports.getVoucherDetailService = function (voucherId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {
            async.series([
                function (callbackInner) {
                    var sql = 'select card_no,user_id from voucher_user_bind where id=?';
                    mysqlUtil.query(sql, voucherId, function (err, result) {
                        if (result != null && result.length > 0) {
                            var voucher = {
                                cardNo: result[0].card_no,
                                cardUrl: cardUrl + '?backUrl=' + encodeURIComponent(cardH5Url + '?cardNo=' + result[0].card_no + '&userId=' + result[0].user_id + '&html=voucher')
                            };
                            callbackInner(err, voucher);
                        } else {
                            var msg = {
                                message: '代金券不存在'
                            };
                            logger.error('getVoucherDetailService' + err);
                            callbackInner(msg, null);
                        }
                    })
                },
                function (callbackInner) {
                    var sql = 'select r.retailer_name,r.address,r.phone,r.retailer_icon from retailer r,retailer_community_bind b where b.community_id=? and b.retailer_id=r.id';
                    mysqlUtil.query(sql, user.community._id, function (err, result) {
                        result.forEach(function (temp) {
                            if (temp.retailer_icon == null || temp.retailer_icon == '') {
                                temp.retailer_icon = 'http://66xiaoqu.babytreeimg.com/group1/M00/00/04/rB75BFTZwwWAF2L-AABUqY8vmBc771.png'
                            }
                        });
                        callbackInner(err, result);
                    })
                }
            ], callback)
        }
    })
};


//================================================== Web后台管理 ==============================================


/**
 * 根据分页查找全部用户
 */
exports.getAllUserService = function (page, callback) {
    var index = Number(page) * listPageSize;
    listPageSize = 10000;//暂时先设置为10000，分页做了再修改
    Users.find(null).populate('community', 'communityName').skip(index).limit(listPageSize).sort('-dateCreated')
        .exec(function (err, results) {
            if (results == undefined || results == null) {
                var msg = {
                    "message": 'get err'
                };
                callback(msg, null);
            } else {
                callback(null, results);
            }
        })
};

exports.findByNameORPhoneService = function (page, input, callback) {

    var query1 = {nickName: new RegExp(input.userName)};

    var query2 = {mobilePhone: new RegExp(input.userPhoneNO)};

    var index = Number(page) * listPageSize;

    if (input.userName == null) {
        query1 = null;
    }
    if (input.userPhoneNO == null) {
        query2 = null;
    }

    //Users.find({$or:[{ nickName:  new RegExp(input.userName) }, { mobilePhone: new RegExp(input.userPhoneNO)}]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
    Users.find({$and: [query1, query2]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
        .exec(function (err, results) {
            if (results == undefined || results == null) {
                var msg = {
                    "message": 'get err'
                };
                callback(msg, null);
            } else {
                callback(null, results);
            }
        })
};

exports.registerUserFromBackOfficeService = function (user, callback) {

    var tempUser = new Users();
    tempUser.userName = user.userName;
    tempUser.email = user.email;
    tempUser.mobilePhone = user.mobilePhone;
    tempUser.userPassword = user.userPassword;
    tempUser.community = user.community;
    tempUser.domainOfExpertise = user.domainOfExpertise;


    if (user.userName) {
        tempUser.huanxinUserName = user.userName;
    } else if (user.email) {
        tempUser.huanxinUserName = user.email;
    } else if (user.nickName) {
        tempUser.nickName = user.nickName;
    } else {
        tempUser.huanxinUserName = user.mobilePhone;
        tempUser.nickName = user.mobilePhone.substr(6);
    }


    tempUser.huanxinPassword = user.userPassword;

    tempUser.community = user.community;
    tempUser.save(callback);

    //环信注册开始
    var http = require('http');

    //构造post数据
    if (user.userName) {

        var post_data = {
            username: user.userName,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    } else if (user.email) {
        var post_data = {
            username: user.email,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    } else {
        var post_data = {
            username: user.mobilePhone,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    }

    //构造链接选项
    var urlOpts = {
        host: 'a1.easemob.com',
        path: '/66xiaoqu/' + huanxinEnv + '/users',
        port: '80',
        method: 'POST',
        headers: {
            "Content-Type": "application/json",
            "Content-Length": post_data.length
        }
    };

    //向环信提交请求
    var request = http.request(urlOpts, function (response) {
        response.on('data', function (chunk) {//请求成功的情况
            logger.debug(chunk.toString());

        });
    }).on('error', function (e) {//请求失败的情况
        logger.debug('error:' + e.stack);
        //删除在数据库中添加的用户
        userService.deleteService(user.userName, user.email, user.mobilePhone, function (err) {
            if (err) {
                logger.error("Failed to register this user - Failed to delete user - " + err.message);
                callback(err);
            } else {
                logger.error("Failed to register this user - succeed to delete user - " + err.message);
                callback(err);
            }
        });
    });
    // write data to request body
    request.write(post_data + "\n");
    request.end();
    //环信注册结束

};


/**
 * userService.js
 *搜索用户
 *author：chenjinzhuan
 * */
exports.searchBackOfficeUserService = function (input, callback) {

    var query1 = {nickName: new RegExp(input.nickName)};

    var query2 = {mobilePhone: new RegExp(input.userPhoneNO)};

    //var query3 = {'communityName': input.communityName};

    var query4 = {dateCreated: {"$gte": new Date(input.dateStart)}};

    var query5 = {dateCreated: {"$lt": new Date(input.dateEnd)}};

    //var index = Number(page)* listPageSize;

    if (input.nickName == null || input.nickName == '') {
        query1 = null;
    }
    if (input.userPhoneNO == null || input.userPhoneNO == '') {
        query2 = null;
    }
    if (input.dateStart == null || input.dateStart == '') {
        query4 = null;
    }
    if (input.dateEnd == null || input.dateEnd == '') {
        query5 = null;
    }


    async.waterfall([
        //根据昵称、手机、起始日期和终止日期查询
        function (callbackInner) {
            //Users.find({$or:[{ nickName:  new RegExp(input.userName) }, { mobilePhone: new RegExp(input.userPhoneNO)}]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
            //Users.find({$and: [query1, query2, query4, query5]}).populate('community', 'communityName').skip(index * page).limit(listPageSize).sort('-dateCreated')
            Users.find({$and: [query1, query2, query4, query5]}).populate('community', 'communityName').sort('-dateCreated')
                .exec(function (err, results) {
                    if (results == undefined || results == null) {
                        var msg = {
                            "message": 'get err'
                        };
                        callback(msg, null);
                    } else {
                        return callbackInner(null, results);
                    }
                });
        },
        //根据小区名称单独查询
        function (results) {
            if (input.communityName == null || input.communityName == '') {
                return callback(null, results);
            }
            for (var i = results.length - 1; i >= 0; i--) {
                if (results[i].community == null || results[i].community.communityName != input.communityName) {
                    results.splice(i, 1);
                }
            }
            return callback(null, results);
        }
    ]);
};

/**
 * userService.js
 * 后台管理用户登录
 *author：chenjinzhuan
 * */
exports.adminLoginService = function (input, callback) {

    var userName = input.userName;
    var password = input.password;

    adminUsers.find({'userName': userName, 'password': password}, function (err, results) {
        if (err) {//异常
            return callback(err, null);
        } else if (results == null || results.length == 0) {//用户名密码不匹配或者用户不存在
            return callback(null, {status: false});
        } else {//用户名密码匹配成功
            return callback(null, {status: true});
        }
    });
};

/**
 *
 * @param communityId
 * @param status
 * @param callback
 */
exports.getAuthenticationUserListService = function (communityId, status, nickname, page, callback) {
    logger.info(communityId + "/" + status + "/" + nickname);

    var opt = {};

    if (communityId == '1' && status == '1') {
        opt = {
            isValid: true
        }
    } else if (communityId == '1' && status != '1') {
        opt = {
            status: status,
            isValid: true
        }
    } else if (communityId != '1' && status == '1') {
        opt = {
            community: communityId,
            isValid: true
        }
    } else {
        opt = {
            community: communityId,
            status: status,
            isValid: true
        }
    }
    async.series([

        function (callbackInner) {


            if (nickname != '1') {

                Users.find({nickName: {$regex: nickname}}, "_id").exec(function (err, result) {

                    var userIds = [];
                    for (var i = 0; i < result.length; i++) {
                        userIds[i] = result[i];
                    }
                    opt.user = {$in: userIds};


                    var index = (Number(page) - 1) * listPageSize;
                    userAuthentication.find(opt, 'user community imageURL promotionCode status dateCreated').skip(index).limit(listPageSize)
                        .populate('user', '_id nickName images roomUnit roomNumber')
                        .populate('community', '_id communityName').sort('-dateCreated').exec(callbackInner);
                })
            } else {
                var index = (Number(page) - 1) * listPageSize;
                userAuthentication.find(opt, 'user community imageURL promotionCode status dateCreated').skip(index).limit(listPageSize)
                    .populate('user', '_id nickName images roomUnit roomNumber')
                    .populate('community', '_id communityName').sort('-dateCreated').exec(callbackInner);
            }
        },
        function (callbackInner) {
            userAuthentication.count(opt, callbackInner);
        }
    ], callback)
};


/**
 * 审核用户认证
 */
exports.examineUserAuthenticateService = function (body, callback) {
    var communityId;
    var huanxinUser;

    userAuthentication.findOne({user: body.user, community: body.community, isValid: true}, function (err, result) {
        if (body.status && result.status) {
            var message = {
                message: '已经通过认证'
            };
            callback(message, null)
        } else {
            async.series([
                function (callbackInner) {
                    userAuthentication.update({
                        'user': body.user,
                        'community': body.community,
                        isValid: true
                    }, {'status': body.status}, callbackInner);
                },
                function (callbackInner) {
                    Users.findOne({_id: body.user}, 'community huanxinUserName nickName images invitedBy').populate('community', '_id communityName').exec(function (err, user) {
                        communityId = user.community._id;
                        huanxinUser = user;
                        callbackInner(null, user.invitedBy);
                    });
                },
                function (callbackInner) {
                    if (body.community == communityId) {
                        Users.update({_id: body.user}, {'authenticationStatus': body.status}, callbackInner);
                    } else {
                        callbackInner(null, null);
                    }
                },
                function (callbackInner) {
                    if (body.status && body.community == communityId) {

                        var message = "你好，你的V认证已经通过，我们将为V用户提供更多，更好的服务，也让你在小区中更与众不同。";
                        toolUtil.pushCustomerServiceMessage(huanxinUser, message);
                        callbackInner(null, null);
                    } else {
                        callbackInner(null, null);
                    }
                },

                function (callbackInner) {
                    if (body.community == communityId) {
                        var status = 0;
                        if (body.status) {
                            status = 1;
                        } else {
                            status = 2;
                        }
                        //个推
                        var content = {
                            f: 3,
                            vStatus: status
                        };
                        var pushData = {
                            uList: [body.user],
                            content: content
                        };
                        toolUtil.putMessageTransmissionPushMQ(pushData);
                    }
                    callbackInner(null, null);
                },
                //更新最后修改日期
                function (callbackInner) {
                    userAuthentication.update({
                        'user': body.user,
                        'community': body.community
                    }, {dateLastModified: new Date()}, callbackInner);
                },
                function (callbackInner) {
                    toolUtil.setUserByToken(body.user);
                    callbackInner();
                }
            ], callback)
        }
    });
};

exports.refuseUserAuthenticateService = function (id, body, callback) {

    var communityId;
    var huanxinUser;

    async.series([
        function (callbackInner) {
            userAuthentication.update({_id: id}, {isValid: false, refusalReason: body.message}, callbackInner);
        },
        function (callbackInner) {

            Users.findOne({_id: body.userId}, 'huanxinUserName community nickName images').populate('community', '_id communityName').exec(function (err, result) {
                communityId = result.community._id;
                huanxinUser = result;
                callbackInner(null, null);
            });
        },
        function (callbackInner) {
            if (body.community == communityId) {

                var message = body.message;
                toolUtil.pushCustomerServiceMessage(huanxinUser, message);

                callbackInner(null, null);
            } else {
                callbackInner(null, null);
            }
        },
        function (callbackInner) {
            if (body.community == communityId) {
                //个推
                var content = {
                    f: 3,
                    vStatus: 0
                };
                var pushData = {
                    uList: [body.userId],
                    content: content
                };
                toolUtil.putMessageTransmissionPushMQ(pushData);
            }
            callbackInner(null, null);
        }
    ], callback)
};

exports.getRecentContactPersonService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {

            recentContact.find({
                userHuanxin: user.huanxinUserName,
                $and: [{otherHuanxin: /\b((?!500500)\w)+\b/}, {otherHuanxin: {$ne: '66customerservice'}}, {otherHuanxin: {$ne: 'superservice'}}]
            }).sort('-time').limit(10).exec(function (err, result) {
                var huanxinIds = [];
                if (result != null && result.length > 0) {
                    result.forEach(function (huanxin) {
                        huanxinIds.push(huanxin.otherHuanxin);
                    })
                }
                var data = [];
                async.eachSeries(huanxinIds, function (id, c1) {
                    Users.findOne({huanxinUserName: id}, '_id nickName images userType authenticationStatus roomUnit community userRole', function (err, result) {
                        if (result != null && user.community._id == result.community._id) {

                            result._doc.roomUnit = !isNaN(result.roomUnit) ? result.roomUnit + '单元' : result.roomUnit;

                            data.push(result);
                        }
                        c1();
                    }).populate('community', 'communityName')
                }, function (err) {
                    callback(err, data);
                });
            });
        }
    })
};

exports.getScoreRank = function (token, pageNo, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {

            var pageSize = 10;

            var fromIndex = (pageNo - 1) * pageSize;
            var toIndex = fromIndex + (pageSize - 1);

            var now = new Date();
            now.setDate(now.getDate() - 1);
            //now.setDate(now.getDate());
            var date = now.getFullYear() + "" + (parseInt(now.getMonth() + 1) < 10 ? '0' + (now.getMonth() + 1) : +(now.getMonth() + 1) ) + (parseInt(now.getDate()) < 10 ? '0' + (now.getDate()) : +(now.getDate()) );

            var communityId = user.community._id;

            var key = "score:rank:community:" + communityId + ":date:" + date;

            logger.info(key);

            redisClient.zrevrange(key, fromIndex, toIndex, 'WITHSCORES', function (err, result) {


                var userList = [];
                var tempResult = [];

                if (result.length >= 8) {

                    for (var i = 0; i < result.length; i++) {
                        if (i % 2 == 0) {
                            tempResult.push({
                                value: result[i],
                                score: result[i + 1]
                            });
                        }
                    }


                    async.eachSeries(tempResult, function (temp, callbackInner) {
                        Users.findOne({_id: temp.value}, 'nickName images gender userType authenticationStatus', function (err, user) {
                            user._doc.ratio = temp.score;
                            userList.push(user);
                            callbackInner();
                        });
                    }, function (err) {
                        callback(err, userList);
                    });

                } else {
                    callback(err, userList);
                }
            });
        }
    })
};

/**
 * 1.6.0重置密码
 * @param input
 * @param callback
 */
exports.resetUserPasswordService = function (input, callback) {
    Users.update({mobilePhone: input.mobilePhone}, {
        userPassword: md5(input.userPassword),
        dateLastModified: new Date()
    }, callback);
};

/**
 * 我的关注列表1.6.0
 * @param token
 * @param ts
 * @param callback
 */
exports.getMyFollowupUsersService = function (token, ts, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            var date = ts == '0' ? new Date() : new Date(Number(ts));

            UserFollowups.find({category: 'user', user: user._id, dateCreated: {$lt: date}}, 'followUser dateCreated')
                .populate('followUser', 'nickName images userType gender authenticationStatus roomUnit showUnit community')
                .sort('-dateCreated')
                .exec(function (err, result) {
                    var data = [];

                    async.eachSeries(result, function (follow, cb) {
                        if (follow.followUser != null) {
                            follow.followUser._doc['followTime'] = follow.dateCreated;

                            if (follow.followUser.roomUnit != null && follow.followUser.roomUnit != '')
                                follow.followUser._doc.roomUnit = !isNaN(follow.followUser.roomUnit) ? follow.followUser.roomUnit + '单元' : follow.followUser.roomUnit;

                            if (!follow.followUser.showUnit) {
                                follow.followUser.roomUnit = undefined;
                            }
                            follow.followUser.showUnit = undefined;

                            Community.findOne({_id: follow.followUser.community}, 'communityName', function (err, comm) {
                                follow.followUser._doc.community = comm;
                                data.push(follow.followUser);
                                cb();
                            });
                        }
                    }, function (err) {
                        callback(null, data);
                    })
                });
        }
    })
};

/**
 * 我的被关注人列表1.6.0
 * @param token
 * @param ts
 * @param callback
 */
exports.getMyBeFollowedUsersService = function (token, ts, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            var date = ts == '0' ? new Date() : new Date(Number(ts));

            UserFollowups.find({category: 'user', followUser: user._id, dateCreated: {$lt: date}}, 'user dateCreated')
                .populate('user', 'nickName images userType gender authenticationStatus roomUnit showUnit community')
                .sort('-dateCreated')
                .exec(function (err, result) {
                    var data = [];
                    async.eachSeries(result, function (follow, cb) {
                        if (follow.user != null) {
                            follow.user._doc['followTime'] = follow.dateCreated;

                            if (follow.user.roomUnit != null && follow.user.roomUnit != '')
                                follow.user._doc.roomUnit = !isNaN(follow.user.roomUnit) ? follow.user.roomUnit + '单元' : follow.user.roomUnit;

                            if (!follow.user.showUnit) {
                                follow.user.roomUnit = undefined;
                            }
                            follow.user.showUnit = undefined;
                            Community.findOne({_id: follow.user.community}, 'communityName', function (err, comm) {
                                follow.user._doc.community = comm;

                                UserFollowups.findOne({
                                    user: user._id,
                                    followUser: follow.user._id
                                }, function (err, result) {
                                    follow.user._doc.isFollowup = result != null;
                                    data.push(follow.user);
                                    cb();
                                });
                            });
                        }
                    }, function (err) {
                        callback(null, data);
                    });
                });
        }
    })
};

/**
 * 我的未读数量1.6.0
 * @param token
 * @param callback
 */
exports.getMyUnreadMessageCountService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            async.parallel([
                function (callbackInner) {
                    SystemMessage.count({
                        'toUser': user._id,
                        readFlag: false
                    }, callbackInner);
                },
                function (callbackInner) {
                    operateMessage.count({user: user._id, readFlag: false}, callbackInner);
                },
                /*  宝宝树66小区二次改造    add   guo.xiaomin  20170802   start   */
                function (callbackInner) {
                    Users.findOne({_id: user._id},  {_id:0,'gagOrNot':1}, callbackInner);
                },
                /*  宝宝树66小区二次改造    add   guo.xiaomin  20170802   end   */
            ], callback)
        }
    })
};

/**
 * 其他用户页1.6.0
 * @param userId
 * @param token
 * @param vCode
 * @param callback
 */
exports.otherUserPageService = function (userId, token, vCode, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            Users.findOne({
                _id: userId
            }, 'community nickName gender images roomUnit showUnit userType authenticationStatus huanxinUserName userRole', function (err, other) {
                if (err || other == null) {
                    callback(ErrorMessage.USER_NOT_EXIST)
                } else {

                    var opt = {
                        isValid: true,
                        createdBy: userId
                    };
                    if (user.community._id == other.community._id + '') {
                        opt.community = user.community._id;
                    } else {
                        opt.aroundCommunity = user.community._id;
                    }

                    async.parallel([
                        function (callbackInner) {
                            Question.count(opt, callbackInner);
                        },
                        function (callbackInner) {

                            var activityOpt = {
                                isValid: true
                            };
                            if (other.community._id + '' == user.community._id) {
                                activityOpt['$or'] = [{'partake.user': userId, aroundCommunity: user.community._id},
                                    {createdBy: userId, community: user.community._id},
                                    {'partake.user': userId, community: user.community._id}];

                            } else {
                                activityOpt['$or'] = [{createdBy: userId, aroundCommunity: user.community._id},
                                    {'partake.user': userId, aroundCommunity: user.community._id}, {
                                        'partake.user': userId,
                                        community: user.community._id,
                                        aroundCommunity: other.community._id
                                    }]
                            }
                            neighbourActivity.count(activityOpt, callbackInner);
                        },
                        function (callbackInner) {
                            var replyOpt = {
                                repliedBy: userId
                            };
                            if (user.community._id == other.community._id + '') {
                                replyOpt['$or'] = [{aroundCommunity: user.community._id}, {
                                    community: user.community._id
                                }];
                            } else {
                                replyOpt['$or'] = [{aroundCommunity: user.community._id}, {
                                    community: user.community._id,
                                    aroundCommunity: other.community._id
                                }]
                            }

                            ugcReply.count(replyOpt, callbackInner);
                        },
                        function (callbackInner) {
                            if (user.community._id == other.community._id + '') {
                                UserFollowups.findOne({user: user._id, followUser: userId}, function (err, result) {
                                    callbackInner(null, result != null);
                                })
                            } else {
                                callbackInner(null, null);
                            }
                        },
                        function (callbackInner) {
                            scoreProxy.invoke('getScoreInfoByUid', [userId + ''], function (err, result) {
                                if (err) {
                                    callbackInner(null, '');
                                } else {
                                    var data = JSON.parse(decodeURIComponent(result));
                                    if (data.status != 0) {
                                        logger.error('getUserScore----' + data.msg);
                                        callbackInner(null, '');
                                    } else {
                                        callbackInner(null, data.data.scoreInfo.currentValue + '');
                                    }
                                }
                            })
                        }
                    ], function (err, result) {

                        if (other.roomUnit != null && other.roomUnit != '')
                            other._doc.roomUnit = Number(vCode) >= 106000 && !isNaN(other.roomUnit) ? other.roomUnit + '单元' : other.roomUnit;

                        if (!other.showUnit) {
                            other.roomUnit = undefined;
                        }
                        other.showUnit = undefined;


                        var data = {
                            user: other,
                            statistics: {
                                question: toolUtil.transformNumber(result[0], 'other'),
                                activity: toolUtil.transformNumber(result[1], 'other'),
                                reply: toolUtil.transformNumber(result[2], 'other'),
                                score: result[4]
                            }
                        };
                        if (result[3] != null) {
                            data.isFollowup = result[3]
                        }
                        callback(null, data)
                    })
                }
            }).populate('community', '_id communityName')
        }
    })
};

exports.otherUserPageNewService = function (userId, token, communityId, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            Users.findOne({
                _id: userId
            }, 'community nickName gender images userType authenticationStatus huanxinUserName userRole').populate('community', '_id communityName city')
                .exec(function (err, other) {

                    if (err || other == null) return callback(ErrorMessage.USER_NOT_EXIST);
                    if (other.community == null) return callback({message: '查看的用户未选择小区'});

                    if (other.huanxinUserName == '66customerservice') other._doc.huanxinUserName = 'superservice';

                    async.parallel([
                        function (callbackInner) {
                            //var args = [redisKey.getUserDataStatisticKey(userId), 'adoptedReply', 'thankedReply', 'questionPraise'];
                            //redisClient.HMGET(args, callbackInner);
                            toolUtil.getUserStatistics(userId, communityId ? communityId : other.community._id + '', callbackInner);
                        },
                        function (callbackInner) {
                            scoreProxy.invoke('getScoreInfoByUid', [userId + ''], function (err, result) {
                                if (err) {
                                    callbackInner(null, '');
                                } else {
                                    var data = JSON.parse(decodeURIComponent(result));
                                    if (data.status != 0) {
                                        callbackInner(null, '');
                                    } else {
                                        callbackInner(null, data.data.scoreInfo.currentValue + '');
                                    }
                                }
                            })
                        },
                        function (callbackInner) {
                            UserFollowups.findOne({user: user._id, followUser: userId}, function (err, result) {
                                callbackInner(null, result != null);
                            })
                        },
                        function (callbackInner) {
                            if (communityId != null) {
                                Community.findOne({_id: communityId}, 'communityName city', callbackInner)
                            } else {
                                callbackInner();
                            }
                        }
                    ], function (err, result) {
                        var data = {
                            user: other,
                            isFollowup: result[2],
                            isShow: true,
                            statistics: {
                                adopt: toolUtil.transformNumber(result[0].adoptedReply, 'other'),
                                thank: toolUtil.transformNumber(result[0].thankedReply, 'other'),
                                praise: toolUtil.transformNumber(result[0].questionPraise, 'other'),
                                score: result[1]
                            }
                        };
                        if (result[3] != null) {
                            data.user.community = result[3]
                        }
                        callback(null, data)
                    });
                });
        }
    });
};
/**
 * 其他用户档案 1.6.0
 * @param userId
 * @param token
 * @param callback
 */
exports.otherUserProfileService = function (userId, token, callback) {
    Users.findOne({_id: userId}, 'birthDate nickName images age gender  hobbies community  homeTown.province homeTown.city userType userPortrait school authenticationStatus job roomUnit showUnit')
        .populate('community', '_id communityName communityAddress').populate('userPortrait', 'portraitURL value')
        .populate('homeTown.province', '_id name')
        .populate('homeTown.city', '_id name')
        .populate('hobbies', '_id value').exec(function (err, result) {
            if (result.showUnit != null && !result.showUnit) {
                result.roomUnit = undefined;
            }
            if (result.community == null) {
                result.community = undefined;
            }

            if (result.homeTown.province == null || result.homeTown.city == null) {
                result.homeTown = undefined;
            }
            result.showUnit = undefined;
            callback(err, result);
        });
};


exports.eachOtherFollowupService = function (user1, user2) {

    Users.find({_id: {$in: [user1, user2]}}, 'community').exec(function (err, uList) {
        if (uList != null && uList.length < 2) return;

        async.parallel([
            function (callback) {
                UserFollowups.findOne({user: uList[0]._id, followUser: uList[1]._id}, function (err, result) {
                    if (result == null) {
                        var temp = new UserFollowups();
                        temp.category = 'user';
                        temp.user = uList[0]._id;
                        temp.fromCommunity = uList[0].community;
                        temp.followUser = uList[1]._id;
                        temp.toCommunity = uList[1].community;
                        temp.save(callback);
                    } else {
                        callback()
                    }
                })
            },
            function (callback) {
                UserFollowups.findOne({user: uList[1]._id, followUser: uList[0]._id}, function (err, result) {
                    if (result == null) {
                        var temp = new UserFollowups();
                        temp.category = 'user';
                        temp.user = uList[1]._id;
                        temp.fromCommunity = uList[1].community;
                        temp.followUser = uList[0]._id;
                        temp.toCommunity = uList[0].community;
                        temp.save(callback);
                    } else {
                        callback()
                    }
                })
            }
        ])
    })
};

/**
 * 1.7.0用户提交认证资料
 * @param token
 * @param input
 * @param callback
 */
exports.postUserAuthenticationDataService = function (token, input, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            var imageURL = input.imageURL;

            userAuthentication.findOne({
                user: user._id,
                community: user.community._id,
                isValid: true
            }, '', function (err, result) {
                if (result != null) {
                    result.imageURL = imageURL;
                    result.save(callback);
                } else {
                    var temp = new userAuthentication();
                    temp.user = user._id;
                    temp.community = user.community._id;
                    temp.imageURL = imageURL;
                    temp.save(callback);
                }
            });
        }
    });
};

/**
 * 1.7.0 我想
 * @param token
 * @param input
 * @param callback
 */
exports.postUserWantService = function (token, input, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {

            var data = {};

            if (input.type == 1) {
                data.type = 1;
                data.content = [input.gender, input.birthday]
            } else if (input.type == 2) {
                data.type = 2;
                data.condition = input.somethingId;
                data.content = [input.somethingValue];
            } else if (input.type == 3) {
                data.type = 3;
                data.condition = input.province._id;
                data.content = [input.province.name, input.city.name];
            }

            async.series([
                function (callbackInner) {

                    var opt = {
                        type: data.type,
                        community: user.community._id,
                        user: {$ne: user._id}
                    };
                    if (data.type != 1) {
                        opt.condition = data.condition
                    }

                    userWant.count(opt, function (err, count) {
                        userWant.find(opt, 'user content dateCreated')
                            .populate('user', 'nickName images userType roomUnit showUnit huanxinUserName').sort('-dateCreated').limit(listPageSize)
                            .exec(function (err, result) {
                                if (result != null && result.length > 0) {
                                    result.forEach(function (want) {

                                        if (opt.type == 1) {
                                            want.content[1] = (moment().diff(moment(want.content[1]), 'years') + 1) + '岁'
                                        }

                                        if (want.user.roomUnit != null && want.user.roomUnit != '')
                                            want.user._doc.roomUnit = !isNaN(want.user.roomUnit) ? want.user.roomUnit + '单元' : want.user.roomUnit;

                                        if (want.user.showUnit != null && !want.user.showUnit) {
                                            want.user.roomUnit = undefined;
                                        }
                                        want.user.showUnit = undefined;
                                    })
                                }
                                callbackInner(null, {
                                    uList: result,
                                    count: count,
                                    opt: data,
                                    community: user.community._id
                                })
                            })
                    });
                },
                function (callbackInner) {
                    var key = 'want:' + user.community._id + ':' + data.type;
                    if (data.type != 1) {
                        key = key + ':' + data.condition;
                    }
                    redisClient.zrevrange(key, 0, 1, function (err, value) {
                        if (value != null && value.length > 0) {
                            value = JSON.parse(value[0]);

                            if (value.category == 'neighbourActivity') {
                                neighbourActivity.findOne({_id: value._id}, 'title desc category images createdBy activityType community dateCreated')
                                    .populate('community', 'communityName')
                                    .populate('createdBy', 'nickName images roomUnit showUnit').exec(function (err, result) {
                                        callbackInner(null, {key: key, ugc: result})
                                    })
                            } else {
                                Question.findOne({_id: value._id}, 'desc category images createdBy community dateCreated')
                                    .populate('community', 'communityName')
                                    .populate('createdBy', 'nickName images roomUnit showUnit').exec(function (err, result) {
                                        callbackInner(null, {key: key, ugc: result})
                                    })
                            }
                        } else {
                            callbackInner(null, {key: key});
                        }
                    });
                },
                function (callbackInner) {
                    var opt = {
                        type: data.type,
                        user: user._id
                    };
                    if (data.type == 2) {
                        opt.condition = data.condition;
                    }

                    userWant.findOne(opt, function (err, result) {
                        if (result == null) {
                            var temp = new userWant(data);
                            temp.user = user._id;
                            temp.community = user.community._id;
                            temp.save(function (err, want) {
                                callbackInner(err, true)
                            })
                        } else {
                            data.dateCreated = new Date();
                            userWant.update(opt, data, function (err, want) {
                                callbackInner(err, false);
                            })
                        }
                    })
                },
                function (callbackInner) {
                    if (data.type == 1) {
                        Dic.find({category: '02', value: '亲子'}, '_id value', callbackInner)
                    } else {
                        callbackInner()
                    }
                },
                function (callbackInner) {
                    if (input.type == 1) {
                        Users.update({_id: user._id}, {
                            children: {
                                gender: input.gender,
                                birthday: input.birthday
                            }
                        }, callbackInner)
                    } else if (input.type == 3) {
                        Users.update({_id: user._id}, {
                            homeTown: {
                                province: input.province._id,
                                city: input.city._id
                            }
                        }, callbackInner)
                    } else {
                        callbackInner()
                    }
                }
            ], callback)
        }
    })
};


exports.getWantDoSomethingListService = function (token, callback) {
    Dic.find({category: '04'}, 'category value').sort('displayOrder').exec(callback);
};

exports.getSameWantUserListService = function (token, ts, input, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            var data = {};

            if (input.type == 1) {
                data.type = 1;
                data.content = [input.gender, input.birthday]
            } else if (input.type == 2) {
                data.type = 2;
                data.condition = input.somethingId;
                data.content = [input.somethingValue];
            } else if (input.type == 3) {
                data.type = 3;
                data.condition = input.province._id;
                data.content = [input.province.name, input.city.name]
            }

            var date = ts == '0' ? new Date() : new Date(Number(ts));

            var opt = {
                type: data.type,
                community: user.community._id,
                user: {$ne: user._id},
                dateCreated: {$lt: date}
            };
            if (data.type != 1) {
                opt.condition = data.condition
            }


            userWant.find(opt, 'user content dateCreated')
                .populate('user', 'nickName images userType roomUnit showUnit huanxinUserName').sort('-dateCreated').limit(listPageSize)
                .exec(function (err, result) {
                    if (result != null && result.length > 0) {
                        result.forEach(function (want) {

                            if (opt.type == 1) {
                                want.content[1] = (moment().diff(moment(want.content[1]), 'years') + 1) + '岁'
                            }


                            if (want.user.roomUnit != null && want.user.roomUnit != '')
                                want.user._doc.roomUnit = !isNaN(want.user.roomUnit) ? want.user.roomUnit + '单元' : want.user.roomUnit;

                            if (want.user.showUnit != null && !want.user.showUnit) {
                                want.user.roomUnit = undefined;
                            }
                            want.user.showUnit = undefined;
                        })
                    }
                    callback(err, result)
                })
        }
    })
};


exports.getWantRecommendUgcService = function (token, input, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {

            var data = {};

            if (input.type == 1) {
                data.type = 1;
                data.content = [input.gender, input.birthday]
            } else if (input.type == 2) {
                data.type = 2;
                data.condition = input.somethingId;
                data.content = [input.somethingValue];
            } else if (input.type == 3) {
                data.type = 3;
                data.condition = input.province._id;
                data.content = [input.province.name, input.city.name]
            }

            var key = 'want:' + user.community._id + ':' + data.type;
            if (data.type != 1) {
                key = key + ':' + data.condition;
            }
            redisClient.zrevrange(key, 0, 1, function (err, value) {
                if (value != null && value.length > 0) {
                    value = JSON.parse(value[0]);

                    if (value.category == 'neighbourActivity') {
                        neighbourActivity.findOne({_id: value._id}, 'title desc category images createdBy activityType community dateCreated')
                            .populate('community', 'communityName')
                            .populate('createdBy', 'nickName images').exec(function (err, result) {
                                callback(null, result)
                            })
                    } else {
                        Question.findOne({_id: value._id}, 'desc category images createdBy community dateCreated')
                            .populate('community', 'communityName')
                            .populate('createdBy', 'nickName images roomUnit showUnit').exec(function (err, result) {
                                callback(null, result)
                            })
                    }
                } else {
                    callback(null, null);
                }
            });
        }
    })
};

exports.buildPushParamsMapService = function (input, callback) {
    var temp = new pushParamsMap();
    temp.params = JSON.stringify(input);
    temp.save(callback);
};

exports.getUserWantPageService = function (token, mapId, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {

            pushParamsMap.findOne({_id: mapId}, function (err, input) {
                if (input == null && input.params != null) {
                    callback({message: '无效的id'})
                } else {
                    input = JSON.parse(input.params);

                    var data = {};

                    if (input.type == 1) {
                        data.type = 1;
                        data.content = [input.gender, input.birthday]
                    } else if (input.type == 2) {
                        data.type = 2;
                        data.condition = input.somethingId;
                        data.content = [input.somethingValue];
                    } else if (input.type == 3) {
                        data.type = 3;
                        data.condition = input.province._id;
                        data.content = [input.province.name, input.city.name]
                    }

                    async.series([
                        function (callbackInner) {

                            var opt = {
                                type: data.type,
                                community: user.community._id,
                                user: {$ne: user._id}
                            };
                            if (data.type != 1) {
                                opt.condition = data.condition
                            }

                            userWant.count(opt, function (err, count) {
                                userWant.find(opt, 'user content dateCreated')
                                    .populate('user', 'nickName images userType roomUnit showUnit huanxinUserName').sort('-dateCreated').limit(listPageSize)
                                    .exec(function (err, result) {
                                        if (result != null && result.length > 0) {
                                            result.forEach(function (want) {

                                                if (opt.type == 1) {
                                                    want.content[1] = (moment().diff(moment(want.content[1]), 'years') + 1) + '岁'
                                                }

                                                if (want.user.roomUnit != null && want.user.roomUnit != '')
                                                    want.user._doc.roomUnit = !isNaN(want.user.roomUnit) ? want.user.roomUnit + '单元' : want.user.roomUnit;

                                                if (want.user.showUnit != null && !want.user.showUnit) {
                                                    want.user.roomUnit = undefined;
                                                }
                                                want.user.showUnit = undefined;
                                            })
                                        }
                                        callbackInner(null, {uList: result, count: count, opt: input})
                                    })
                            });
                        },
                        function (callbackInner) {
                            var key = 'want:' + user.community._id + ':' + data.type;
                            if (data.type != 1) {
                                key = key + ':' + data.condition;
                            }
                            redisClient.zrevrange(key, 0, 1, function (err, value) {
                                if (value != null && value.length > 0) {
                                    value = JSON.parse(value[0]);

                                    if (value.category == 'neighbourActivity') {
                                        neighbourActivity.findOne({_id: value._id}, 'title desc category images createdBy activityType')
                                            .populate('createdBy', 'nickName images roomUnit showUnit').exec(function (err, result) {
                                                callbackInner(null, {key: key, ugc: result})
                                            })
                                    } else {
                                        Question.findOne({_id: value._id}, 'desc category images createdBy')
                                            .populate('createdBy', 'nickName images roomUnit showUnit').exec(function (err, result) {
                                                callbackInner(null, {key: key, ugc: result})
                                            })
                                    }
                                } else {
                                    callbackInner(null, {key: key});
                                }
                            });
                        },
                        function (callbackInner) {
                            if (data.type == 1) {
                                Dic.find({category: '02', value: '亲子'}, '_id value', callbackInner)
                            } else {
                                callbackInner()
                            }
                        }
                    ], callback)
                }
            })
        }
    })
};

var QuestionStore = mongoose.model('question_store');
/**
 * 初始化小区引导帖子
 */
exports.initCommunityQuestionService = function (communityId) {


    // QuestionStore.find({storetype: 'init'}, function (err, result) {
    //     if (result != null && result.length > 0) {
    //         Users.findOne({mobilePhone: '66customerservice'}, 'nickName', function (err, service) {
    //             result.forEach(function (question) {
    //                 var temp = new Question();
    //                 temp.community = communityId;
    //                 temp.desc = question.desc;
    //                 temp.images = question.images;
    //                 temp.category = question.category;
    //                 temp.tag = question.tag;
    //                 temp.createdBy = service._id;
    //                 temp.fromFlag = 'service';
    //                 temp.topBeginDate = new Date();
    //                 temp.topEndDate = moment().add(5, 'day').toDate();
    //                 temp.save();
    //             })
    //         })
    //     }
    // })
    //
    // Community.update({_id: communityId}, {dateEffective: new Date(), isInit: true}).exec();

    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170814   start   */
    QuestionStore.find({storetype: 'init'}, function (err, result) {
        if (result != null && result.length > 0) {
            Users.findOne({mobilePhone: '66customerservice'}, 'nickName', function (err, service) {
                result.forEach(function (question) {
                    var temp = new Question();
                    temp.community = communityId;
                    temp.desc = question.desc;
                    temp.images = question.images;
                    temp.category = question.category;
                    temp.tag = question.tag;
                    temp.createdBy = service._id;
                    temp.fromFlag = 'service';
                    temp.topBeginDate = new Date();
                    temp.topEndDate = moment().add(5, 'day').toDate();
                    temp.save();
                })
            })
        }
    });

    Community.update({_id: communityId}, {dateEffective: new Date(), isInit: true}).exec();
    /*  宝宝树66小区二次改造    add   guo.xiaomin  20170814   end   */

};

/* 宝宝树66小区二次改造 新老用户登录勾选新用户协议 add wangcan 20170927 start */
/**
 * 更新用户协议版本
 */
exports.updateProtocolVersionService = function (mobilePhone, callback) {
    var protocolVersion = newProtocolVersion; // 取得最新用户协议版本号
    Users.update({mobilePhone: mobilePhone}, {protocolVersion: protocolVersion}, function (err, proUpdateResult) {
        if (err) {
            logger.error("更新最新用户协议版本号出错");
            callback(err);
        } else {
            callback(null, proUpdateResult);
        }
    });
};
/* 宝宝树66小区二次改造 新老用户登录勾选新用户协议 add wangcan 20170927 end */

/*  宝宝树66小区二次改造    add   guo.xiaomin  20170912   start   */
exports.pushMessageToFollowers = function(userId, category, callback) {
    logger.debug('pushMessageToFollowers start...');
    async.parallel([
        function(callbackInner) {
            Users.findOne({'_id': userId}, 'nickName', function (err, tempUser) {
                callbackInner(null, tempUser._doc.nickName);
            });
        },
        function(callbackInner) {
            var option = {"category" : "user", 'followUser': userId};
            UserFollowups.find(option).exec(function (err, results) {
                callbackInner(err, results);
            });
        }
    ], function(err, result) {
        var nickName = result[0]; // 被关注的人的昵称
        var categoryName = '闲置';
        if(category == 'share') {
            categoryName = '说说';
        } else if(category == 'question') {
            categoryName = '问问';
        }
        if(result[1] != null && result[1].length > 0) {
            result[1].forEach(function (temp) {
                logger.debug('push to user...' + temp.user);
                logger.debug('您关注的用户' + nickName + '发布了一个' + categoryName + '!');
                // toolUtil.putMessageBusinessMQ({'msgType': 'followed_user_send_msg', 'userId': temp._id, 'nickName': nickName, 'category': category});
            });
        } else {
            logger.debug('当前用户没有人关注:' + nickName + '(' + userId + ')');
        }
        callback(null, null);
    });
};

// 根据手机号查询当前用户是否是66小区用户 1:是;0:不是
exports.isBabyTreeUser = function(mobilePhone, callback) {
    Users.count({'mobilePhone': mobilePhone}, function (err, tempCount) {
        callback(null, tempCount > 0 ? 1: 0);
    });
};
/*  宝宝树66小区二次改造    add   guo.xiaomin  20170912   end   */

// 修改密码极验证2次
exports.captchValidateChangePassword = function (req, callback) {
    var captcha = new Geetest({
        geetest_id: geetest_id,
        geetest_key: geetest_key
    });

    var userId = toolUtil.getUserObjIdByToken(req.params.token); // 用户ID
    var deviceId = req.params.deviceId; // 设备ID
    logger.debug("captchValidateChangePassword:userId + deviceId..." + userId + " + " + deviceId);
    redisClient.get('captchChangePassword:fallback:' + userId + ":" + deviceId, function (err, value) {
        captcha.validate((value=="false"|| value == null ?false:true), {
            geetest_challenge: req.body.geetest_challenge,
            geetest_validate: req.body.geetest_validate,
            geetest_seccode: req.body.geetest_seccode
        }, function (err, success) {
            if (err) {
                logger.error(err);
                callback({status:false, message:err});
            } else if (!success) {
                // 二次验证失败
                logger.error("验证失败");
                callback({status:false, message:"验证失败"});
            } else {

                redisClient.setex('captchChangePassword:fallback:' + userId + ":" + deviceId, 86400, true);
                callback(null, success);
            }
        });
    });
};

/*  宝宝树66小区五期   add  重置申请状态 guo.xiaomin  20171207   start   */
// 重置申请状态
exports.resetApplyStatus = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            var userId = user._id;
            var communityId = user.community._id;
            RoleApply.findOne({"user": userId, "community": communityId}).sort({"dateCreated": -1}).exec(function (err, temp) {
                var status = null;
                if(temp) {
                    status = temp.status;
                    logger.debug("用户所在小区..." + userId + "@" + communityId + "@" + status);

                    var saveRoleApply = new RoleApply();
                    saveRoleApply.user = userId;
                    saveRoleApply.community = communityId;
                    saveRoleApply.city = temp.city._id;
                    saveRoleApply.type = temp.type;
                    saveRoleApply.name = temp.name;
                    saveRoleApply.phone = temp.phone;
                    saveRoleApply.address = temp.address;
                    saveRoleApply.specialty = temp.specialty;
                    saveRoleApply.status = -9; // 未申请过
                    saveRoleApply.specialty = temp.specialty;
                    saveRoleApply.startDateTime = new Date();
                    saveRoleApply.endDateTime = new Date();

                    saveRoleApply.save(function (err, result) {
                    });
                    logger.debug("用户新增一条-9的申请数据..." + userId + "@" + communityId);
                    callback(null, "OK");
                } else {
                    callback(null, "NG");
                }
            });
        }
    });
};
/*  宝宝树66小区五期   add  重置申请状态 guo.xiaomin  20171207   end   */